[squeak-dev] Re: The Trunk: Kernel-eem.474.mcz

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Fri Jul 23 12:42:35 UTC 2010


2010/7/23 Tobias Pape <Das.Linux at gmx.de>:
>
> Am 2010-07-23 um 07:39 schrieb Andreas Raab:
>>
>> However, I do take Travis' point about compile time expressions. Here the whole point is that you really want the expression to be reevaluated when the defining code changes which is not easily done the above (it's possible but bothersome).
>
> I think its good to point out that it is possible to
> differentiate between one-time-expressions
> and compile-time expressions. I think an expression
> executed once, however, not at compile time can make
> a pretty good lazy initializer in the sense you mentioned.
>  Alas, I must admit that I’m not aware of an example that
> cannot be equally good expressed with the …ifNil: variant
> as with the [] once  variant.
>

We must distinguish compile time evaluation (Dolphin ##() ) and lazy
evaluation (at first execution like [] once).
The later is better because more robust to load order...
The former suffer at code loading : some class/method used by
initialization could be missing.

[] once is equivalent to ifNil: [] indeed... But when I see some code
crippled with ifNil: just to solve an initialization problem, I feel
it's stinking personnally. It is unecessarily parasitically explicit.
If I have a Shared variable used at ten places, then I have to pollute
10 places with ifNil:  for caring of lazy initialization...

We could have a lazy evaluation scheme like this:
- every shared variable value is accessed by sending #value (at bytecode level)
- every shared variable binding is initialized with an UninitializedBinding
- UninitializedBinding>>value is an indirection
   ^value
        ifNil: [UninitializedException raise]
        ifNotNil: [self value: value value)]
- UninitializedBinding>>value: anObject
    self become: (InitializedBinding key: key value: anObject)
- some initializer methods have a pragma
MyClass>>doSomeInitialization
    <initialize>
    ClassVar := someObject someMessage.
- compiling above method triggers some initialization like
   (MyClass sharedVariables at: #ClassVar) setUninitialzedValue:
(MessageSend receiver: MyClass selector: #doSomeInitialization).
- UninitializedBinding>>setUninitialzedValue: anEvaluator
    value:= anEvaluator
- InitializedBinding>>setUninitialzedValue: anEvaluator
   self become: (UninitializedBinding key: key value: anEvaluator)

The positive effects are:
- variables are initialized lazily as long as someone provides an
<initialize> annotation.
- you don't have to cripple code with nil
- load order and initialization order are relaxed (think of the mess
of class initialization at Monticelllo or any other package manager
load)
- every time you change the initializer, you reinitialize the shared variable

I let you comment on the negative effects (complex architectures, time
spent in sending value at runtime instead of fetching 2nd ivar
etc...).

Nicolas

>
> So Long,
>        -Tobias
>



More information about the Squeak-dev mailing list