Surprising semantics

Ingvar von Schoultz ingvar-v-s at comhem.se
Thu Jul 17 17:34:37 PDT 2008


These are some impressions looking at what I expect from the
language, and how some things in the specification can cause
confusion.

I would have contributed here during the discussions, but I
discovered the mailing lists just a couple of days ago.

I expect the compiler's interpretation of program-code text
to be close to my intuitive understanding of what the text
says. It's very unfortunate if keywords have unexpected
meanings that cause mysterious side effects.

If I learn that ECMAScript will let me change my var(iables)
into const(ants) I expect this to turn them into constants, in
the sense that trying to change their value will be considered
an error. It's very disappointing that by default they are
instead defined to have the baffling and mysterious behavior
of silently ignoring an attempt to change them, acting as if
no error had occurred.

You'll have to keep this oddity in mind at all times, and even
then errors related to this will sometimes cause symptoms to
appear far from where the error is, costing quite some time
to explore. Why doesn't my program change its behavior even
though I'm provoking changes? Where in this big program's
complicated sequence of events is the change silently, secretly
lost?

If instead you use var, at least the problems that can come
from this will tend to give symptoms closely connected to the
incorrect change in the value.

So this is a disappointing red flag: Don't use const, it is
likely to cause baffling problems and unlikely to help.

Unfortunately there's another problem with const that is much
more important. I often use constants for conditional settings:

     if (Debugging)
     {   var DatabaseName = "TestDatabase";
         var DisplayCount = 5;
     }
     else
     {   var DatabaseName = "RealDatabase";
         var DisplayCount = 15;
     }

The redundant "var"s are a defensive habit, omitting them would
be a warning about accesses outside the current scope.

If I haven't been warned, and hear that ECMAScript understands
"const", I expect that replacing "var" with "const" will change
the above from variables into constants. The keyword in no way
suggests that it will hide them from view. If they disappear
I'll inevitably consider such a completely unrelated side effect
a compiler bug.

Because of this I'm unhappy about the conclusions of ES3.1 that
the visibility scope of "const" should be the enclosing brace-
delimited block. Such intricate semantics hidden in words that
express something completely unrelated will make the language
seem difficult and fraught with hidden surprises.

I much prefer what ES4 says in various places on the website:
that you express this localness with "let const" and "let function".
One block-scope keyword for all block-scope visibility. Consistency
and clarity.

However this brings me to the unfortunate word "let". Although
this word has a precise and clear technical meaning for the
initiate, for us in the unwashed masses I can't see that the
English word "let" gives even the remotest suggestion of local
containment. In fact it suggests very clearly that it's related
to the "=" that so often follows:

     if (x == 5)
     {   let y = 3;
     }

"If x is 5, then let y equal 5." There's an almost inescapably
strong suggestion that "let" is a phrasing of the assignment
expression, and therefore can't have anything to do with the
braces.

I think ECMAScript should be easily accessible to us in the
unwashed masses. It becomes much more intuitively accessible
if it uses a word that strongly implies localness:

     {   if (x == 5)
         {   local y = 3;
         }
         local const Debugging = false;
         for (local Key in List)
             ++List [Key];
     }

You get plain English sentences that express quite accurately
what they're supposed to mean. The programmer won't be the
least surprised if a value gets hidden by "local".

When people want to write let expressions, if they have to
write "local" instead of "let" I don't think this will cause
problems. I'm sure the initiate are sophisticated enough that
they can adapt to this.

Apart from this, I think the scoping arrangements would
become significantly simpler and clearer if the language
made a very clear, really visible, intuitively accessible
distinction between two different types of block, and allowed
you to choose either type of block wherever this made sense.

My suggestion is to introduce a clearly distinct new and
better block. This block should be delimited by {{ and }}
if it's at all possible, and I think it is. No keyword,
just {{ and }}. This better block would bind vars, consts
and functions, just like function scopes do. In fact function
scopes and {{ }} would be the same thing, as seen by the
programmer.

An important advantage with {{ }} is that you can keep
everything contained without tedious and error-prone
repetition of local (or let) everywhere. And the scoping
is prominently visible and clearly structured.

It may seem odd that I say that adding yet another scoping
construct would make it simpler and easier to learn, but
if it's built this way it becomes conceptually clear, free
of hidden intricacies, easy to explain. The delimiters
{{ and }} suggest that you are walling things in with thicker
walls, so that hoisting can't get past. Nicely intuitive.
Especially for programmers who put braces at left it becomes
very clear indeed. And I'm sure syntax-coloring editors will
help making the scoping clear at a glance.

The terminology might distinguish between the two types of
block by talking about strong and weak blocks, where strong
means thick walls that you can't hoist out of, and weak means
that the block can only capture things that are marked local
(or let), and everything else gets hoisted out.

In fact I think a terminology with strong versus weak blocks
is clearer than the current terminology, where one type of
block is called block and the other is called variable object.

I'm sorry if this comes across as a series of complaints. All
in all I'm delighted with the many enticing improvements! But
listing all the nice things here wouldn't make for interesting
reading. And so it may sound much more negative than my overall
delighted and enthusiastic feelings.

-- 
Ingvar von Schoultz

------- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)




More information about the Es4-discuss mailing list