[racket] Nested scope in D vs Racket

From: Shriram Krishnamurthi (sk at cs.brown.edu)
Date: Sat Aug 21 11:39:08 EDT 2010

On Sat, Aug 21, 2010 at 10:53 AM, Matthias Felleisen
<matthias at ccs.neu.edu> wrote:
>
> It's not about teaching, it's about freedom of expression.
> This is one of the least problems for programmers and I can't
> think of a bug I have seen that involved this issue.

Radio Free Matthias is broadcasting from back his Scheme days.

Perhaps I should clarify.

Here's a simple Scheme program:

----------
#lang r5rs

(define (bar x)
  (lambda ()
    (let ((x x))
      x)))

(define f (bar 20))
----------

Matthias would tell you to "diagram" to make sure you understand where
the X's come from.  If you're lazy you can even have DrRacket do it
for you, and everything is as expected.  When you execute:

  (f)
  --> 20

In other words, there is nothing surprising at all here, so you might
as well give programmers their freedoms.

Sometimes, however, languages get confused.  Here's the "same" program
"translated" into JavaScript (courtesy of Arjun Guha, from our ECOOP
2010 talk):

----------
function bar(x) {
  return function() {
    var x = x;
    return x;
  };
}
var f = bar(200);
----------

There's no Check Syntax for JavaScript, so you have to draw the arrows
by hand.  You can't be misled by its purported similarities to Scheme
because the arrows are rather more weird, and

  f()
  --> undefined

Now let's go to HtDP: there is no "let", only "local".  (And, keep in
mind that Racket is not Scheme.)

----------
#lang racket

(define (bar x)
  (lambda ()
    (local ([define x x])
      x)))

(define f (bar 20))
----------

Now we can again get DrRacket to draw our arrows, and they look rather
familiar.  Sure enough:

  (f)
  --> #<undefined>

Or if you prefer the new direction we're going in:

----------
#lang racket

(define (bar x)
  (lambda ()
    (define x x)
    x))

(define f (bar 20))
----------

with the same arrows, and the same outcome:

  (f)
  --> #<undefined>

Obviously, Matthias can explain *what* happened in every case (and the
"what" is, I believe, a bit different in the JavaScript and the two
Racket cases).  But you have to wonder, at what cost.

Shriram


Posted on the users mailing list.