Ask HN: Help me choose the best syntax for a new language

5 points by ne01 ↗ HN
Hi HN friends,

I have a hard time deciding between the following options for variable scope syntax. The language is supposed to be very easy to learn.

A) Local variables start with `@`.

Pros: Easy to identify global and local variables. You have easy access to global variables inside a scope.

Cons: Users have to learn variable scope from the start.

Example:

  <set var="x">3</set>
  <scope>
    <set var="@x">4</set>
    Local x is <put>@x</put>.
  </scope>
  Global x is <put>x</put>.
Result:

  Local x is 4.
  Global x is 3.

B) Local variables silently overshadow existing global variables.

Pros: Easier to learn (no more `@` in the syntax).

Cons: You loose access to the global `x` -- the only way to access a global variable is to make sure it has a unique name.

Example:

  <set var="x">3</set>
  <scope>
    <set var="x">4</set>
    Local x is <put>x</put>
  </scope>
  Global x is <put>x</put>
Result:

  Local x is 4.
  Global x is 3.
C) Reversed system: use `@` for global. I personally don't like this because there would be too many `@`.

D) ... Any other suggestions?

Thanks :)

3 comments

[ 2.1 ms ] story [ 25.1 ms ] thread
A few more alternatives:

- B, with an explicit syntax for accessing the "global" x. For instance, ::x, or global::x.

- B, with a compile-time warning or error if you shadow a name. This would be my preferred alternative.

I choose B and make variable overshadowing a compiler warning.
A mix of B and C.

Variables bound within a scope should be able to shadow variables bound in parent scopes, but global vars should be made obvious when they are used within the codebase - visually marking global variables is a good thing.

Example:

  <set var="@x" global>3</set>
  <scope>

      <set var="x">4</set>

      <put>x</put> // 4
      <put>@x</put> // 3

      <scope>
         <set var="x">10</set>

         <put>x</put> // 10
         <put>@x</put> // 3
      </scope>

      <put>x</put> // 4
      <put>@x</put> // 10
  </scope>