diff --git a/multiple-let.txt b/multiple-let.txt new file mode 100644 index 0000000..a1d7dbc --- /dev/null +++ b/multiple-let.txt @@ -0,0 +1,20 @@ +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.