[E-Lang] the return of `return'
Darius Bacon
darius@accesscom.com
Mon, 18 Jun 2001 01:27:12 -0700
After reading the March syntax threads and chatting with Zooko and
SteveJ I have some thoughts to add. The upshot is I don't favor any
of the ideas below, but do favor finding out more about how people
take to the existing syntax.
Zooko proposed we could have a guard `:retAny' that lets through only
values specially wrapped by a `return'; anything else is coerced to
null. This is meant to solve two problems: Java people are used to
saying `return', and they might get in the habit of using the :any
guard everywhere, not understanding what it's for. If we make :retAny
the default, programmers would have to explicitly reveal results using
`return'.
But a `return' with no control-flow implications would still surprise
the target audience -- who expect it to return immediately, not just
wrap a value. We could rescue this by calling it `reveal', but that's
giving up on familiarity.
Or we could have a `return' that returns immediately. That creates
several problems.
First, E has nested definitions -- which method do we return from?
Suppose it's the innermost. Then
for key => value in collection { ... return(x) ... }
expands into (roughly)
collection iterate(def _(key, value) { ... return(x) ... })
so the `return' doesn't return from the function a beginner would
expect. This could be fixed by giving `for' an uglier expansion. Or,
we could change the definition syntax to explicitly name the return
escaper, like
def foo(collection) return {
for key => value in collection { ... return(x) ... }
}
which would be like, in current E,
def foo(collection) :any {
escape return {
for key => value in collection { ... return(x) ... }
null
}
}
This preserves the security properties of Zooko's idea, at the cost of
an unfamiliar definition syntax. But familiarity was our main goal.
Second, in E we'd expect return to be, like break and continue, a
locally-bound name for an escaper function -- while in the C world
it's special syntax. C programmers will try to write `return 42'
instead of `return(42)' and be annoyed when it doesn't work. We could
add special syntax for return, break, and continue, then. (Holding my
nose here.)
Third, if `return' is required then common E patterns are just too
painful:
def fooMaker(x) {
return(def foo {
to blat() { ... }
})
}
Some ideas on this one:
1. Make `return' optional. Then the :retAny guard would be no help.
2. Define some special syntax just for the above pattern, like
ughDef fooMaker(x) {
def foo {
to blat() { ... }
}
}
With all these unappealing alternatives, I have to wonder how shocking
E's expression style really is for our users. There are at least two
popular expression-style languages: Perl and the sh family. Should
introductory docs compare it to Perl and sh? I'm afraid that might
drive more people away than it'd help.
-Darius