Putting contexts in the proper context.

I've mentioned before that I was prototyping two different approaches to handling the operating context for the decnum-dynpmcs. Here are some results of the prototyping and some explanations of the choices made.

Why do we need a context?
This 'context' I'll keep referring to is one of the abstractions provided by the decNumber library. The library provides the usual operations on numbers, addition subtraction, multiplication, division and so forth, but in order to maintain generality this operations have a set of user-definable parameters like the precision (expressed in decimal digits) the rounding mode and some others. All of this parameters are bundled together in the decContext structure, that must be passed to all operations along with it's operands. But this doesn't mean that there is only one context, you can have as many as you want and use whichever suits your purposes.

In order to accommodate the (unknown to us) needs of future users we should allow them to play with the decContext structure. Okay, they can alter the context, but you can't just pass it to operations. Take an add for example:
$P0 = new 'DecNum'
$P1 = new 'DecNum'
$P2 = new 'DecNum'
$P0 = $P1 + $P2
That last line of pir will call the add vtable of "$P1" (prototype: "PMC *add(DecNum value, PMC* dest)") with "$P2" as 'value' and "$P0" as 'dest'. No context to be seen there. The context must be passed implicitly, inside the code of the dynpmc. That is easy enough to do, we stash a context somewhere and use it when needed, but it also raises questions: Is this context global or do we keep one for each number? Let's analyze both cases:

Contexts for everyone!
This means every DecNum has a context, they all start out with the same one, but the user can change the details for every number separately. This has some usability consequences, assuming the context for every operation is provided by the destination PMC, take the following pir:
$P0 = new 'DecNum'
$P1 = new 'DecNum'
$P2 = new 'DecNum'
$P3 = new 'DecNum'
$P2.'set_rounding_mode'("ROUND_UP")
$P3.'set_rounding_mode'("ROUND_DOWN")
"$P2 = $P0 + $P1"
"$P3 = $P0 + $P1"
Now $P2 can be different from $P3 if rounding took place, that could surprise some people. Also, if you don't like the default rounding mode you'll have to change it for every PMC that you'll assign to, that's bound to annoy some people. And this makes non-obvious the fact that the context only affects the operations, not the numbers. So, let's check out the alternative.

There can only be one!
This means that there is only one context, and all operations are performed with it. And to make clean that the context is a separate entity, we create a separate (singleton) PMC. If you need to change the context you just "new DecNumContext" and alter that one, the next new you perform will retrieve the already created one. The previous example becomes:
$P0 = new 'DecNum'
$P1 = new 'DecNum'
$P2 = new 'DecNum'
$P3 = new 'DecNum'
$P4 = new 'DecNumContext'
$P4.'set_rounding_mode'("ROUND_UP")
$P2 = $P0 + $P1"
$P4.'set_rounding_mode'("ROUND_DOWN")
"$P3 = $P0 + $P1"
With just one caveat, all future operations will "ROUND_DOWN" unless you change it again. This way is less likely to surprise users. They know that the context is a global object, and it's easier to explain to them that the context is only used for operations. This also makes consistent arithmetic the default, while retaining the possibility of emulating per-PMC context with a sub (change context, operate, restore context).

There's just one and you'll have to share it.
Given that both approaches are basically equivalent in implementation complexity it came down to usability, where global-context has the advantage of containing less surprises. Another factor for me was flexibility, the fact that global context can easily emulate per-PMC context (but not vice-versa) tipped the scales further in favor of global context. It has sane defaults, gives users enough flexibility to implement whatever madness they can come up with and is subclassable to provide further madness if it ever becomes necessary.
That sounds to me like the right approach, and if ever turns to be wrong it's easier to fix than the other way around ;)