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

Re: expressions vs. statements



David Simmons writes:
> I hear the expression of major concern or conclusions about the negative
> aspects/inherent problems in languages that do not have what are being
> termed "statements" that do not evaluate to a "value". 

Boy, everybody's so TOUCHY here.  It's not as if we're accusing each
other of having bad breath or poor armpit hygiene.  We're just talking
about advantages and disadvantages of particular programming languages
and programming language features here.  No need to start bouncing off
the walls and "using" scare "quotes".  Take two Perls and call me in
the morning.

> However, of all the (many) things people have complained or been
> concerned about in Smalltalk. I have never (not once) heard this
> (everything has a value, there are no "statement" distinctions) as being
> a problem in Smalltalk where every operation is effectively a message
> and thus every operation has a "value". 

The particular problem I brought up, which Pixel corroborated, is that
a function in Perl or C whose primary purpose is to have side effects
nevertheless returns a value, the value of the last expression it
evaluates.  So you need to be careful about changing the last
expression a Perl or C function evaluates, because you might break
things accidentally.

I don't think that's debatable, and I don't think it's debatable that
that's a problem.  It's debatable how big a problem it is; I think
it's not a very big problem.  In fact, I don't know where I'd look for
a piece of code that exhibits it.  But I know I've run into it in the
past.

I don't really know Smalltalk, but it seems to me that in Smalltalk,
this dubious feature is completely absent.  It's true that blocks
return the value of their last expression, but blocks are different
from functions; the closest analogue to a function in Smalltalk is a
method.  Methods are not blocks.  They do not return the last
expression evaluated.  If they do not explicitly return a value with a
^ statement (maybe there's some Algolish spelling of this too, like :=
for _?) they return the object they are being invoked on.

It appears to me that in Smalltalk, blocks are used differently from
functions.  You can generally tell from the context where a block is
defined whether it is intended to yield a useful value or not, and if
you change your mind about whether or not it should, you generally
only have to make local changes.

> I surmise this has more to do with [how Smalltalk programmers are
> industrious wizards who focus on the right things and love their
> mothers]...

I don't really think that's relevant to this discussion.  I think it's
purely explicable in terms of language semantics.

Michael Fischer writes:
> You already know that a function or block "returns" the last
> statement contained within it. So why would you ask Perl to do what
> you did not want it to do?

Because it's shorter and clearer to ask Perl to do that.

The point is that you didn't explicitly ask for anything, and when you
don't explicitly ask for anything, Perl does something anyway, just in
case it was what you wanted.  You wrote a function that said:

sub frotz {
   my ($wibble, $gurble) = @_;
   $wibble->frob('frotzed', $gurble);
}

and frotz ended up returning whatever $wibble->frob returned, and some
code (possibly your own) may be depending on frotz returning this
value.  You can't tell by looking.  You can avoid this as follows:

sub frotz {
   my ($wibble, $gurble) = @_;
   $wibble->frob('frotzed', $gurble);
   return;
}

But that's verbose and ugly, extra work to write and to read, so
people don't do that.  It's not usually worth the effort for the tiny
advantage it provides.

Note that this is not a problem at all if you write functions whose
purpose in life is to perform side effects.  It's obvious from looking
that the function's return value is used: if it weren't, there'd be a
comment to that effect.  It's only in languages like Perl, which
support both imperative and functional programming very effectively,
that you have a problem.

Michael Fischer quoted Pixel:
> > agreed for while/for. My only problem is with if_then_else which
> > return value is useful. Alas in perl you can't write "return if ()
> > ..." to disambiguate.
> 
> No?
> 
>         return if $bar; # returns the special 'undef' value

No.  You can't write return if ($a) { $x } else { $y }, to make it
clear that you're returning the return value of the if statement.
Trailing statement modifiers are not the same thing, although I know
that's what it sounded like Pixel was talking about.  But you *can*
write it in any of these ways:

The C approach:
return $a ? $x : $y;  # (if $x and $y are expressions, not statements)

The Python or Pascal approach:
if ($a) {
    return $x;
} else {
    return $y;
}

The do approach:
return do { if ($a) { $x } else { $y } };