-
Notifications
You must be signed in to change notification settings - Fork 0
Description
variables bound in the local part of a local-in-end decl have the body decl as their
scope
Variables bound in the local section are also available in the subsequent lines in the local section:
local
val x = "strung"
val y = x
in
val () = print y
endif a value variable is bound at top level in a structure, but not exported, it has
Open scope (not the remaining sequence of decls in the structure)
It sounds like you want applied occurrences through a module identifier to refer exactly to the binding occurrence in a struct definition. I agree that it's desirable for scoping to not depend on module-level static semantics, but what about the following:
structure S = struct
val f = fn x => x
val g = f true
end :> sig
val f : int -> int
val g : bool
endDo we want one variable, f, to have two different types, 'a. 'a -> 'a inside the struct and int -> int outside the struct?
Perhaps, and maybe there are problems with this approach too, but perhaps variables should only refer to identifiers that don't come after a period, and identifiers that do follow a period should instead be treated more like record labels, without the whole ceremony involving environments. After all, structure members don't require any sort of shadowing, do they? Otherwise, if you still wanted them to be variables, you would need to handle the signature ascription example above in some way.
Value variables and module variables will (probably) have an assoiciated unique
_dynamic_ variable used to refer to the runtime value to which it is bound during
execution.
Syntactic variables don't refer to a unique dynamic variable:
val bn = fn v => fn () => v
val th1 = bn 1
val th2 = bn 2There's one syntactic variable, v, that refers to two dynamic variables, one assigned to 1 and one assigned to 2.
Note that if type variables have explicit binding points, no lexical distinction
(like a leading apostrophy) is needed for type variables. We could have a convention
that they be capitalized alphanumeric (and a corresponding convention that tycons be
alphanumeric with an initial lower case letter).
If there is no lexical distinction between tycons and tyvars, then they should be in the same namespace as well. Consider the following hypothetical MsML (I'm using F#-esque angle brackets to avoid confusion in this specific example, not to suggest them for MsML):
datatype a = A
datatype b = B
datatype c<a> = CA of a | CB of bYou expect the a in CA to refer to the type variable, shadowing the datatype, while the b in CB instead refers to the datatype. It makes most sense to think of b and both as as all being in the same namespace, since you can't tell whether a variable in a type refers to a tycon or a tyvar just by syntactic categories alone, without looking at what's in scope.