On 27 August 2012 12:16, Levente Uzonyi <le...@elte.hu> wrote:
> On Sun, 26 Aug 2012, Frank Shearar wrote:
>
>> On 26 August 2012 17:55, Levente Uzonyi <le...@elte.hu> wrote:
>>>
>>> On Sun, 26 Aug 2012, Frank Shearar wrote:
>>>
>>>> That sounds like a reasonable workaround to address Mariano's
>>>> immediate problem :)
>>>
>>>
>>>
>>> I don't see what other issues are there to solve. :)
>>
>>
>> Then you should go reread my article, and the articles it references
>> :) Both have examples of how undelimited dynamic variables don't work
>> sensibly with delimited continuations. Kiselyov goes further and shows
>> how they _cannot_ work sensibly.
>
>
> I took a look why DynamicVariable doesn't work with Control and I found that
> the reason is that Control doesn't play well with #ensure:.
> Let's see it in this example:
>
> DynamicVariable value: 1 during: [
>     [ DynamicVariable value: 2 during: [
>         [ :k | DynamicVariable value ] shift ]] reset ]
>
> When #reset is sent, the value of the variable is 1, then it starts
> evaluating the receiver block. The value is set to 2 and then #shift occurs.
> #shift cuts the stack back, so the argument of #ensure:, which would restore
> the value of the variable in the process' environment to 1 is never
> evaluated.
>
> So Control breaks the contract of #ensure:, because it starts the evaluation
> of its receiver, but doesn't evaluate its argument:

The shift looks like it cuts out that part of the stack responsible
for setting the DynamicVariable to 2. In fact, rather, it DOES cut it
out. The problem is that the value's not stored on the stack, so the
stack cutting doesn't behave as it should. So you have a
well-implemented dynamic variable, and a well-implemented delimited
continuation, and yet when you add them together you get broken
behaviour.

My point is that you _cannot_ have undelimited dynamic variables and
delimited continuations behaving well together.

Hence, if you're slicing stacks, you _cannot_ just use dynamic
variables because they will not behave as they should. If you need a
dynamic variable when slicing a stack, you need to use a delimited
dynamic variable, which _will_ behave sensibly.

Other than claims of higher performance (which would probably require
VM changes to remove the need for all the stack-walking caused by the
resumable exceptions), there's really no reason to choose undelimited
dynamic variables: they're as expressive, but can't be combined with
delimited continuations. And you want delimited continuations because
undelimited continuations (call/cc and friends) not only suck but suck
_hard_. Oh, and of course we have continuations whether we like them
or not - thisContext. (In fact a fork is a delimited continuation.)

frank

> x := 0.
> [
>         [
>                 x := 1.
>                 [ :k | x ] shift ]
>                         ensure: [ x := 2 ] ] reset.
> "==> 1"
>
>
>>
>> Serialising a running process implicitly creates a delimited
>> continuation. Ergo, Fun Times!
>>
>> frank
>>
>>> Anyway, here's a highly
>>> untested example of what I had in my mind:
>>> http://leves.web.elte.hu/squeak/StackSerializableDynamicVariable.st
>>
>>
>> Yep, using resumable exceptions to implement delimited dynamic
>> variables. That's exactly what Control does, only without
>> DynamicVariable necessarily polluting the global namespace.
>
>
> The most common use case of DynamicVariable involves accessing the variable
> from "unrelated" places. Using the global namespace is an easy way to avoid
> passing the variable around all the time. It's basically the same as
> subclassing Notification (which is a common practice - a pattern - to
> implement dynamic variables) from this POV.
>
>
>>
>>> Is uses a method in Process which is not present in current images:
>>>
>>> environmentAt: key ifAbsentPut: aBlock
>>>
>>>         ^(env ifNil: [ env := Dictionary new ]) at: key ifAbsentPut:
>>> aBlock.
>>
>>
>> Current _Pharo_ images, maybe. I'm pretty sure I looked at a trunk
>> image with it in the last few hours (but obviously am too lazy to
>> actually go check :/)
>
>
> I just wrote this method, so I'm pretty sure it's not present in any image.
> :)
>
>
> Levente
>
>>
>> frank
>>
>>> Levente
>>>
>>
>>
>

Reply via email to