[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