Message cascades: can they be always transformed into a sequence?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Message cascades: can they be always transformed into a sequence?

Stefan Marr-4
Hi:

I got a little problem with message cascades, and since I already missed a few details the first time, I wonder whether I am overlooking something now again.

My question is, whether it is always possible to flatten a cascade into a surrounding sequence of statements (method/block).

I am introducing temporary variables for that, and am wonder whether there could be anything I am overlooking with respect to the evaluation order.
Thus, are there constructs where I would change evaluation order by pulling out normal sends and put the results into temporary variables?

I obviously need to make sure that if I flatten them, that I order receivers and arguments correctly. Is there anything else that could hinder flattening?

(Ah, and I am happy to ignore reflection, thisContext, or exceptions.)

Here two examples:
---> original:
testCascadedSends
        | assoc |
        assoc := Association key: #foo value: 0.

        assoc value: (1 + 2);
              value: assoc value + 2;
              value: assoc value + 5.

        self assert: 10 equals: assoc value.


testCascadedNotInSequence
        | assoc |
        assoc := Association key: #foo value: 0.

        assoc value: (assoc value: 1;
                            value: 2;
                            yourself).

        self assert: assoc equals: assoc value.
<---

---> transformed:
testCascadedSends
        | assoc t* |
        assoc := Association key: #foo value: 0.

        assoc value: (1 + 2).
        t1 := assoc value.
        assoc value: t1 + 2.
        t2 := assoc value.
       assoc value: t2 + 5.

        self assert: 10 equals: assoc value.


testCascadedNotInSequence
        | assoc t* |
        assoc := Association key: #foo value: 0.

        assoc value: 1.
        assoc value: 2.
        t1 := yourself.
        assoc value: t1.

        self assert: assoc equals: assoc value.
<---


Thanks
Stefan

--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


Reply | Threaded
Open this post in threaded view
|

Re: Message cascades: can they be always transformed into a sequence?

Eliot Miranda-2


On Tue, Dec 13, 2011 at 6:45 AM, Stefan Marr <[hidden email]> wrote:
Hi:

I got a little problem with message cascades, and since I already missed a few details the first time, I wonder whether I am overlooking something now again.

My question is, whether it is always possible to flatten a cascade into a surrounding sequence of statements (method/block).

I am introducing temporary variables for that, and am wonder whether there could be anything I am overlooking with respect to the evaluation order.
Thus, are there constructs where I would change evaluation order by pulling out normal sends and put the results into temporary variables?

No. Cascades are simply a syntactic sugar for binding to a temporary, so

   expr message1; ...; messageN

is syntactic sugar for

   | t |
   ...
   t := expr.
   t message1.
   ...
   t messageN.

The implementation simply creates an anonymous temporary on the stack and reads it using dup, effectively push expr, dup, send, dup, send, pop.


I obviously need to make sure that if I flatten them, that I order receivers and arguments correctly. Is there anything else that could hinder flattening?

(Ah, and I am happy to ignore reflection, thisContext, or exceptions.)

Here two examples:
---> original:
testCascadedSends
       | assoc |
       assoc := Association key: #foo value: 0.

       assoc value: (1 + 2);
             value: assoc value + 2;
             value: assoc value + 5.

       self assert: 10 equals: assoc value.


testCascadedNotInSequence
       | assoc |
       assoc := Association key: #foo value: 0.

       assoc value: (assoc value: 1;
                           value: 2;
                           yourself).

       self assert: assoc equals: assoc value.
<---

---> transformed:
testCascadedSends
       | assoc t* |
       assoc := Association key: #foo value: 0.

       assoc value: (1 + 2).
       t1 := assoc value.
       assoc value: t1 + 2.
       t2 := assoc value.
      assoc value: t2 + 5.

       self assert: 10 equals: assoc value.


testCascadedNotInSequence
       | assoc t* |
       assoc := Association key: #foo value: 0.

       assoc value: 1.
       assoc value: 2.
       t1 := yourself.
       assoc value: t1.

       self assert: assoc equals: assoc value.
<---


Thanks
Stefan

--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: <a href="tel:%2B32%202%20629%202974" value="+3226292974">+32 2 629 2974
Fax:   <a href="tel:%2B32%202%20629%203525" value="+3226293525">+32 2 629 3525





--
best,
Eliot

Reply | Threaded
Open this post in threaded view
|

Re: Message cascades: can they be always transformed into a sequence?

Stéphane Ducasse
> Stefan

you should pay attention to what is the receiver of a cascade

because this is really the receive of the first message involved in the cascade.

        OrderedCollection new add: 35; add: 45; yourself

this is anOrderedCollection and not OrderedCollection but you probably know that.

Stef

> No. Cascades are simply a syntactic sugar for binding to a temporary, so
>
>    expr message1; ...; messageN
>
> is syntactic sugar for
>
>    | t |
>    ...
>    t := expr.
>    t message1.
>    ...
>    t messageN.
>
> The implementation simply creates an anonymous temporary on the stack and reads it using dup, effectively push expr, dup, send, dup, send, pop.
>
>
> I obviously need to make sure that if I flatten them, that I order receivers and arguments correctly. Is there anything else that could hinder flattening?
>
> (Ah, and I am happy to ignore reflection, thisContext, or exceptions.)
>
> Here two examples:
> ---> original:
> testCascadedSends
>        | assoc |
>        assoc := Association key: #foo value: 0.
>
>        assoc value: (1 + 2);
>              value: assoc value + 2;
>              value: assoc value + 5.
>
>        self assert: 10 equals: assoc value.
>
>
> testCascadedNotInSequence
>        | assoc |
>        assoc := Association key: #foo value: 0.
>
>        assoc value: (assoc value: 1;
>                            value: 2;
>                            yourself).
>
>        self assert: assoc equals: assoc value.
> <---
>
> ---> transformed:
> testCascadedSends
>        | assoc t* |
>        assoc := Association key: #foo value: 0.
>
>        assoc value: (1 + 2).
>        t1 := assoc value.
>        assoc value: t1 + 2.
>        t2 := assoc value.
>       assoc value: t2 + 5.
>
>        self assert: 10 equals: assoc value.
>
>
> testCascadedNotInSequence
>        | assoc t* |
>        assoc := Association key: #foo value: 0.
>
>        assoc value: 1.
>        assoc value: 2.
>        t1 := yourself.
>        assoc value: t1.
>
>        self assert: assoc equals: assoc value.
> <---
>
>
> Thanks
> Stefan
>
> --
> Stefan Marr
> Software Languages Lab
> Vrije Universiteit Brussel
> Pleinlaan 2 / B-1050 Brussels / Belgium
> http://soft.vub.ac.be/~smarr
> Phone: +32 2 629 2974
> Fax:   +32 2 629 3525
>
>
>
>
>
> --
> best,
> Eliot
>