Working on a statically typed language with type inference and streamlined syntax, and need to make final decision about syntax for variable declaration versus assignment. Specifically I'm trying to choose between:
// Option 1. Create new local variable with :=, assign with =
foo := 1
foo = 2
// Option 2. Create new local variable with =, assign with :=
foo = 1
foo := 2
Creating functions will use =
regardless:
// Indentation delimits blocks
square x =
x * x
And assignment to compound objects will do likewise:
sky.color = blue
a[i] = 0
Which of options 1 or 2 would people find most convenient/least surprising/otherwise best?
Best Answer
There are many more aspects one should consider when settling for assignment/declaration syntax, than simple
=
vs.:=
bikeshedding.Type inference or not, you will want a syntax for explicit type annotations. In some type systems, inference may not be possible without occasional explicit annotations. There two possible classes of syntax for this:
int i
in C. Some languages use postfix types likei int
, (Golang to a certain degree).:
or::
. Sometimes, this declares the type of a name:let i : int = 42
(e.g. Ocaml). In an interesting spin of this, Julia allows a programmer to use type assertions for arbitrary expressions, along the lines ofsum = (a + b):int
.You may also want to consider an explicit declaration keyword, like
var
,val
orlet
. The advantage is not primarily that they make parsing and understanding of the code much easier, but that they unambiguously introduce a variable. Why is this important?If you have closures, you need to precisely declare which scope a variable belongs to. Imagine a language without a declaration keyword, and implicit declaration through assignment (e.g. PHP or Python). Both of these are syntactically challenged with respect to closures, because they either ascribe a variable to the outermost or innermost possible scope. Consider this Python:
Compare with a language that allows explicit declaration:
Explicit declarations allow variable shadowing. While generally a bad practice, it sometimes makes code much easier to follow – no reason to disallow it.
Explicit declarations offer a form of typo detection, because unbound variables are not implicitly declared. Consider:
versus:
You should also consider whether you would like to (optionally) enforce single-assignment form, e.g through keywords like
val
(Scala),let
, orconst
or by default. In my experience, such code is easier to reason about.How would a short declaration e.g. via
:=
fare in these points?:
operator and assigment via=
, theni : int = 42
could declare a variable, the syntaxi : = 42
would invoke inference of the variable, andi := 42
would be a nice contraction, but not an operator in itself. This avoids problems later on.x := expression
orexpression =: x
. However, this has no significant difference to the=
relation, except that the colon draws attention to one name. Simply using the:=
for similarity to maths is silly (considering the=
abuse), as is using it for similarity to Pascal.We can declare some more or less sane characteristics for
:=
, like:But in practice, things get murky. What happens when you have multiple assignments (which you should seriously consider), like
Should this throw an error because
x
is already declared in this scope? Or should it just assignx
and declarey
? Go takes the second route, with the result that typo detection is weakened:Note that the “RHS of typing-operator is optional” idea from above would disambiguate this, as every new variable would have to be followed by a colon:
Should
=
be declaration but:=
be assignment? Hell no. First, no language I know of does this. Second, when you don't use single-assignment form, then assignment is more common than declaration. Huffman-coding of operator requires that the shorter operator is used for the more common operation. But if you don't generally allow reassignment, the=
is somewhat free to use (depending on whether you use=
or==
as comparison operator, and whether you could disambiguate a=
from context).Summary
Personal opinion
I am fond of declaration keywords like
val
ormy
. They stand out, making code easier to grok. Explicit declarations are always a good idea for a serious language.