[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.

Live well,

More information about the bitc-dev mailing list