S, Philippe Marschall piše:
> On 07/01/2011 12:47 PM, Janko Mivšek wrote:
>> S, Julian Fitzell piše:
>>> 2011/6/30 Janko Mivšek <[email protected]
>>>
>>> Whole point is that this is a non-blocking code, in contrast to
>>> continuation based approach like in Seaside, where similar code would
>>> block and wait until dialog component returns answer.
>>>
>>> Janko, what are you talking about? If it's not blocking, it's just a
>>> callback. Of course Seaside can do the same thing: you just use
>>> #show:onAnswer:.
>>
>> Isn't the whole point of Seaside and continuations to enable worklow
>> like in below example from the HPI Seaside tutorial? This code is
>> blocking until the call: returns, isn't that so?
>>
>> From HPI tutorial [1], chapter 5-Forms, figure 5-2 :
>>
>> (self call: self taskEditor)
>> ifTrue: [aTask copyFrom: self taskEditor task]
>>
>> Text bellow: "Even better, Seaside remembers the position in your code
>> and runs it from there again, after the called component finished. This
>> means, #call: blocks your current component, that is your callback
>> evaluation, waits for the called component to be finished, and
>> afterwards goes on with your callback. "
>
> Yes, but continuations don't block a Process. All they do is allow you
> to write code that is more readable.
Yes, technically it doesn't block that process because it must return
something to the browser, but method execution actually blocks on that
point. This blocking is not as hard as blocking like on long I/O, but it
is still. While on the other side a non-blocking style continues
execution of that method instead. Here is the point, and main diffenrec
of blocking vs. non-blocking styles.
> Instead of
>
> self call: self taskEditor [ :value |
> value ifTrue: [
> aTask copyFrom: self taskEditor task ] ]
>
> you can write
>
> (self call: self taskEditor)
> ifTrue: [aTask copyFrom: self taskEditor task]
>
> There is no Process in the background waiting or anything.
>
> In this simple case the benefit may not be that obvious but look at the
> case with only two steps.
>
> first := self askForFirstObject.
> second := self askForSecondObject.
> (first aSelector: second)
> ifTrue: [ self something ]
> ifFalse: [ self somethingElse ]
Asynchronous way would be something like:
self askForFirstObject
onAnswerDo: [:first |
self askForSecondObject
onAnswerDo: [:second |
(first aSelector: second)
ifTrue: [self something]
ifFalse: [self somethingElse]
]
]
This surely looks less nice than your example but it is closer to event
driven nature of browser and web apps. And because such workflow is
actually rare, it is IMHO not worth such a big expense in framework
complexity.
Best regards
Janko
--
Janko Mivšek
Aida/Web
Smalltalk Web Application Server
http://www.aidaweb.si