[bitc-dev] Quick haskell question
wren ng thornton
wren at freegeek.org
Fri Aug 13 16:03:15 PDT 2010
Jonathan S. Shapiro wrote:
> Mark P. Jones <mpj at cs.pdx.edu> wrote:
> In the following program, for example, we get an
>> output of 1 with lexical scoping or 2 with dynamic scoping.
>> x := 1
>> f := \y -> y + x
>> x := 2
>> print (f 0)
>> I can see how this might appear to tie in with the "left of
>> the site of use" idea that you mentioned, but that's just an
>> incidental detail, not an intrinsic part of the definition.
> Oh dear. Our difference of understanding might be rather deeper than I had
> thought. So first, let me confirm that by ":=" you mean
Whether := means assignment to a location in memory or introduction of a
new variable name is immaterial. The question of scoping is whether we
have the lambda expression capture values from the current environment
based on the textual representation of the program, or whether it
contains references into the runtime environment.
If := is assignment, then lexical scope is gained by having lambdas copy
values from the environment into their closure. We didn't say (\y -> y +
&x) so we have no reason to believe the programmer wanted the memory
location of x rather than it's current value. If we interpret the lambda
as implicitly having those reference sigils, then we get dynamic scope.
If := is variable introduction then we get lexical scope if the lambda
captures the x which is in scope according to the program text at the
time it's defined. The third statement is just introducing a new
variable which shadows the old one; it's not illegal in the slightest.
If we wanted dynamic scope, then we simply have lambdas delay looking up
their variables until the time the function is called (instead of
looking them up when the function is constructed and storing them in a
> I'm actually surprised that you say this. The implicit forward reference
> rule seems to imply that top-level bindings are formed in a letrec
> environment. Which is fine, but given this, the convention of using LET to
> introduce them seems (to me) a little odd.
In Haskell, every "let" is a letrec. Top-level definitions are also in a
rec environment. This is not ML where you need to tell the compiler
about mutually recursive groups.
> So far as I can tell, the "where" construct in Haskell is just a
> syntactically unusual let binding.
Depends what you mean by "syntactically". Where-clauses have a wide
scope that let-expressions don't. E.g., with guards, the where-clause
scopes over all branches of the guard; This can't be expressed with a
let-expression unless we get rid of the guard syntax first.
More information about the bitc-dev