finn-lang/multiple-let.txt

21 lines
1.4 KiB
Plaintext
Raw Permalink Normal View History

1. It is valid for a name to occur in the body of a function.
2. It is valid for a name to occur outside the body of a function as long as there are no cycles of such occurrences.
A simpler version:
1. It is valid for a name to occur in the body of a function.
2. It is valid for a name to occur in the definition of a name that is later in the binding list.
e.g. let a = 5 and b = a in ...
It's actually more complicated than this. The OCaml definition of static constructivity doesn't just specify that a name can only occur in the body of a function; instead, it also specifies a set of valid nesting forms, *none of which is a function call.* Otherwise, you could end up with something like
let rec a = (fun()->b)() and b = (fun()->a)() in a
which is nonsense.
So what I need is approximately this:
1. An expression is valid if it is statically constructive with respect to each defined name and it is not immediately linked to each defined name.
- Statically constructive basically means that the expression doesn't have to compute anything at runtime.
2. An expression is valid if it only refers to names defined before it in the binding list.
- A more flexible rule with a more complex implementation would be to check an occurs graph for cycles.
3. An expression is valid if it only contains valid subexpressions.
OCaml also stipulates something about array constructors with an abstract element type, but I don't understand that one yet.