[squeak-dev] Re: [Pharo-project] #ensure: issues

Igor Stasenko siguctua at gmail.com
Thu Mar 4 01:26:49 UTC 2010

2010/3/4 Levente Uzonyi <leves at elte.hu>:
> On Thu, 4 Mar 2010, Igor Stasenko wrote:
>> On 4 March 2010 01:56, Nicolas Cellier
>> <nicolas.cellier.aka.nice at gmail.com> wrote:
>>> 2010/3/4 Levente Uzonyi <leves at elte.hu>:
>>>> On Thu, 4 Mar 2010, Nicolas Cellier wrote:
>>>>> 2010/3/3 Levente Uzonyi <leves at elte.hu>:
>>>>>> On Wed, 3 Mar 2010, Andreas Raab wrote:
>>>>>>> On 3/3/2010 2:07 PM, Levente Uzonyi wrote:
>>>>>>>> On Wed, 3 Mar 2010, Igor Stasenko wrote:
>>>>>>>>> i don't get it. Just before that, you said: ' I'd expect it to be
>>>>>>>>> evaluated no matter what happens.' ?
>>>>>>>>> But now you saying that it may not be executed in some conditions
>>>>>>>>> (when user pressing abandon button, causing process to be
>>>>>>>>> terminated).
>>>>>>>> It's simple: don't terminate process X from another process if
>>>>>>>> process
>>>>>>>> X
>>>>>>>> is executing a termiation block (aka #ensure: block). Or if you
>>>>>>>> terminate it, make sure that the execution of the block will
>>>>>>>> continue
>>>>>>>> somehow (I don't care how).
>>>>>>> You're missing Igors point which is that in his example the halt /
>>>>>>> Transcript *was* in the ensure block and as a result you're
>>>>>>> contradicting
>>>>>>> yourself here. Let's go back to Igor's example:
>>>>>>> [self boom ] ensure: [ self halt. Transcript show: 'boom']
>>>>>>> The halt is inside the ensure block. If you terminate the process
>>>>>>> from
>>>>>>> the
>>>>>>> debugger, it would be logical from your statement that the Transcript
>>>>>>> message would be executed - after all it's " executing a termiation
>>>>>>> block
>>>>>>> (aka #ensure: block)" and so it can't be terminated by your
>>>>>>> reasoning.
>>>>>>> However, when Igor was pointing this out you replied with "I didn't
>>>>>>> say
>>>>>>> that. I said evaluate it the same way as normal code." which is
>>>>>>> inconsistent
>>>>>>> with the other statement.
>>>>>> That shows my lack of knowledge about how the debugger works.
>>>>>>>> I think every user of #ensure: expects that the termination blocks
>>>>>>>> are
>>>>>>>> executed even if the process which is executing the receiver of
>>>>>>>> #ensure:
>>>>>>>> is terminated. And it actually happens in all but this case.
>>>>>>> The question of terminating processes is always tricky. I don't think
>>>>>>> that
>>>>>>> your proposal would actually work in practice - it could easily
>>>>>>> result
>>>>>>> in
>>>>>>> processes that cannot be terminated due to a simple bug in an ensure
>>>>>>> block.
>>>>>>> Personally, I'd rather say that the more useful behavior would be
>>>>>>> something
>>>>>>> along the lines of saying that process termination either skips the
>>>>>>> current
>>>>>>> ensure block (assuming there's a bug and it should get the heck out
>>>>>>> of
>>>>>>> it
>>>>>>> but try to evaluate the remaining ones) or that there need to be two
>>>>>>> terminations - one that is 'soft' and won't allow ensure blocks to be
>>>>>>> skipped and one that is 'hard' (kill -9 hard) and just ignores all
>>>>>>> the
>>>>>>> ensure blocks.
>>>>>> I'm only saying that normal usage (aka #terminate) shouldn't do
>>>>>> unexpected
>>>>>> things like this.
>>>>>> If you read the comment of Process >> #terminate, you may assume that
>>>>>> #ensure: and #ifCurtailed: blocks will be excuted even if you use
>>>>>> #terminate, but that's not true.
>>>>>> "Stop the process that the receiver represents forever.  Unwind to
>>>>>> execute
>>>>>> pending ensure:/ifCurtailed: blocks before terminating."
>>>>>> Levente
>>>>> The only way I see to solve your problem would be to execute the
>>>>> unwind block in another process...
>>>>> Quite technical and costly !
>>>> It's our problem. Just look at the senders of #ensure: and imagine what
>>>> will
>>>> happen if the termination block is not evaluated.
>>>> I think there's another way (though it might be my lack of knowledge
>>>> again).
>>>> After suspending the process which is about to be terminated we can
>>>> check if
>>>> it's executing a termination block. It it's not, we are safe to continue
>>>> the
>>>> termination, otherwise we can do something else which ensures that the
>>>> termination block is evaluated.
>>> Maybe...
>>> Unfortunately, you did not tell how you will distinguish well behaved
>>> unwind-blocks from Igor's example...
>> Yes, then what prevents me from writing:
>> [ [ ] ensure: [ self doCrazyThings ] ] fork.
> What prevents you from writing: Object superclass: Object. ?
> Nothing, but you don't do that, do you?
So, why at all, you care about using #ensure: then? If you putting
everything up to the hands of developer,
then obviously you won't need to use this message, because you always
know that you're running a reliable code which
will always let you to run your things in the end. :)

>> and now given assumption that any code which placed inside ensure
>> block should always run to the end, without chances being terminated,
>> will have ill side effects.
> You can terminate it (maybe not the usual way).
that's the point. Why do we need two (or more) ways to terminate a process?

>> The #ensure: means, that interpreter will have a chance to enter that
>> block eventually, but it should not mean that it will keep running the
>> code there until normal or non-local return from that block.
> Then it doesn't ensure anything at all, so it should be called
> #tryToEvaluateThisToo:.
in fact, this is the actual behavior :)
If i press the power button on your PC, or plug out the power cord,
any #ensure: blocks will have no chances to run either way.
So, relying on something, which is not reliable is a fallacy :)

> Levente
>> Othewise, you losing a way to terminate unwanted, ill-behaved process.
>>> Nicolas
>>>> Levente
>>>>> Nicolas
>>>>>>> Cheers,
>>>>>>>  - Andreas
>> --
>> Best regards,
>> Igor Stasenko AKA sig.

Best regards,
Igor Stasenko AKA sig.

More information about the Squeak-dev mailing list