One useful but much simpler change compared to what the OP suggests, is to have a different syntactical notation for defining vs changing a binding. For ex, keep =
for defining, and introduce :=
or =:
(or other) for changing the binding of the previously defined variable (re-assignment).
I think when we program we already have this different intent in mind (“I’m going to define this to be…” , “I’m going to change that var to…”), so it will not be any mental cost to actually convey that intent when we write the code.
So it’s a low-hanging fruit that I think most dynamic or scripting langs don’t collect.
I suspect doing so, can result in compiler being able to catch more errors, and perhaps optimize the code better, and perhaps also give more options to solve the scope problem (as this github reply by @jeff.bezanson ).
I guess it could be introduced at first as optional, and if most agree, then in future mandatory.
EDIT: I found that this(or essentially this) idea was also proposed, independently, by @Balance
,and with more background details, here , here