[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: expressions vs. statements



In SmallScript/Smalltalk everything is an object, and every operation is
a message. Which means every operation results in an object. So, as this
discussion is attempting to define things, Smalltalk has no concept of a
"statement". 

The "default" rule in Smalltalk is that the last expression executed
provides the value of an expression. For some expressions, they are
explicitly defined to return/evaluate-as <nil> (the singleton of
<UndefinedObject>).

So we can write expressions like:

    [:i| expr1] whileTrue: [:j| expr2].

Where the <i> value is the result of the last <expr2>, and the <j> value
is the result of the last <expr1>. And the initial seed value if <i> is
<nil>.

We can write:

    |r| := if(expr) 
    [:i| 
        ...
    ] 
    else 
    [:i|
        ...
    ].

Where <i>, for either case, will be the object returned by <expr>. The
value of <r> will be the last expression evaluated in either the
eqv-true or eqv-false block (context/closure).

If we write:

   |r| := if(expr) [...].

Then if <expr> is eqv-true, then <r> is set to the last expression
evaluated in the eqv-true block. But, if <expr> is eqv-false then <r> is
set to the <expr> value itself.

Same rules apply for other sugar forms:

    unless(...)
    assert(...)
    while(...)
    do [...] while(...)
    until(...)
    do [...] until(...)
    switch(...) [...]
    try [...] ...catches...fault...finally.
    etc.

And you can design/write your own control structures to do anything you
want including tail-call looping, etc. 

    Method behavior: Object [
    myLoop(expr)
        ^if (self()) [:v|tail:^myLoop(expr(v))]
    ]

The notion that everything is an object, and that expression results get
injected into "apparent" control forms is often exploited for lazy
initializers. Commonly, this is done using the binary-message #? that
tests to see if a value is <nil>. I say apparent, because all (looping)
control forms are really built from messaging that utilizes tail calls,
and or (optionally-labeled) branches.

   ^var ? [var := initExpr]

    expr !? [v:...].

-- Dave S. [SmallScript LLC]

SmallScript for the AOS & .NET Platforms
David.Simmons@SmallScript.com | http://www.smallscript.org


> -----Original Message-----
> From: owner-ll1-discuss@ai.mit.edu
[mailto:owner-ll1-discuss@ai.mit.edu]
> On Behalf Of Paul Prescod
> Sent: Tuesday, December 18, 2001 8:01 PM
> To: ll1-discuss@ai.mit.edu
> Subject: Re: expressions vs. statements
> 
> Paul Graham wrote:
> >
> > This is actually a question people on this list might
> > have interesting opinions about.  Does distinguishing
> > between expressions and statements buy you anything in
> > expressive power?  I have often wondered about what
> > the point of this distinction was...
> 
> One thing you to be careful of with infix languages is not allowing
> assignment to look almost the same as equality testing in an
expression
> context. Contrary to what someone said on the list today, Python does
> not have this problem.
> 
> Also, it is debatable what the "right thing" for an expression like
this
> to return is:
> 
> k = while foo():
>        print "abc"
>        print "def"
>        print "ghi"
> 
> I guess it would return None (Python's nil/null thing)? Allowing
people
> to assign the results of a while loop just seems obfuscatory and thus
> un-pythonic.
> 
> In Perl, you often see code like this:
> 
> print "abc";
> print "def";
> 5;  # returns 5
> 
> That's just weird to me...the value of the last statement in a block
is
> just the value of the last statement in a block. If you want it to be
> the value of the block you should say so. And if we're going to have
> while loops that return values that are not useful (like None) then
why
> even allow you to pretend that the while loop is an expression?
> 
> Finally, Python tries to encourage people to code in a similar style
at
> the micro-level and express their creativity at the macro level. This
> makes other people's Python code easier to read. So you will always
see
> this:
> 
> if a:
>    j=5
> else:
>    j=6
> 
> and never:
> 
> j = if a: 5 else: 6
> 
>  Paul Prescod