Some thoughts on the 'reveal' operator Chip Morningstar (chip@communities.com)
Thu, 23 Sep 1999 16:59:31 -0700 (PDT)

<Note: These are some remarks I made to MarkM in a correspondence I had with him earlier today as I was giving him some feedback on his draft FC'00 paper. He suggested that as thse concerns the language design in general rather than the paper in particular, I ought to share them more broadly, so here (in slightly edited form) they are.>

The reveal operator ("^") is a new addition to E for me. I thought it was a typo when I first saw it. I think I understand what the motivation for this was but I also think it's really icky from a human-factors perspective to have to, in essence, put an explicit "return" statement in *every* block. (It's also problematic to my eyes to have such a significant operation expressed by such a small and hard to see character glyph, though I imagine people with a lot of Smalltalk experience will be more used to it.) In particular, in the example:

define factorial(n) {

      ^if (n <= 0) {

^1
} else {
^n * factorial(n-1)
}

}

The reveal on the two inner result expressions seems clear enough, but I found the reveal on the 'if' to be quite surprising and counterintuitive, since I'm not (yet) used to thinking of statements with a statement-like syntax as expressions. This is particularly the case in this example since you need both the inner and outer reveals to actually return a result; omitting one but not the other in this example yields useless crud:

define factorial(n) {

      if (n <= 0) {

^1
} else {
^n * factorial(n-1)
}

}

*Looks* right, but will be (in C terms) a function returning void. Whereas:

define factorial(n) {

      ^if (n <= 0) {
         1
      } else {
         n * factorial(n-1)
      }

}

is just wrong. I would expect it to (a) throw an exception (effectively crashing the program in this example), (b) silently do something wrong (very bad), or (c) get caught by the compiler (which will feel to the programmer like one of those pedantic complilation errors where the compiler is objecting to some purely formal deviance rather than to something substantive, the kind of error where you tend to think "hey, if the compiler knew *that*, why didn't it just do the right thing?" -- never mind that the right thing isn't actually 100% obvious, that's what programmers will think).

I understand that this is trying to make revelation explicit, presumably so that it becomes a deliberate act (for example, so that a function does not inadvertantly reveal information that was not meant to be revealed, simply because that information happened to be the last thing computed). That's a laudable goal, but I suspect the mechanism will prove cumbersome. Falling back on the custom of using the value of the last expression in a block as the value of the block seems to me a more pragmatic design. If we need to have an explicit value that denotes a non-result for the "I'm not really returning anything" case, that's OK with me.