Open danilopedraza opened 5 months ago
The reason for having one syntax for declaring and another for assingning is that names can be reused in different scopes. For example:
let f(n) := 2*n
let g := n -> (
let f(k) := 3*k,
f(n)
)
f(2) # this is 2*2
g(2) # this is 3*2
A note on the behavior of this: assignments can only alter the current scope. I think this is good for sane code.
I'm having some thoughts related to how to handle mutation. First, I don't want it to be global, JS-style. It is proved to create problems. However, I see the use of assignmets useful when expressing procedures in an imperative way, so restricting to the current scope could be too much. For example, in this nested for-loop there is a new scope for every loop:
let table := [[someValue(i, j) for j in 0..width] for i in height]
var a := 0
for i in height:
for j in width:
a := a + table[i][j]
This means that if mutation is restricted to the current scope, mutation of the value a
would not be possible.
Note: I decided to define mutable values with the var
keyword.
Assignments are now naively implemented.
Here is an idea on how to restrict assignments: Limit them to the scope of a function. This is, assignments in a function can only alter values in that scope. Here is an example:
var x := 0
let f(n) :=
x := n # cannot do this
for i in 0..10 do
x := i # can do this
I'm not sure if this rule should be enforced with anonymous functions.
I didn't implement the restrictions yet. Right now, mutation can occur everywhere.
The language should let the user change the value of an existing symbol. After all, I'm not that compromised with functional style; I just promote it. I think of this syntax: