tags:

views:

38

answers:

2

Hi ! I am reading DrRacket document http://docs.racket-lang.org/guide/binding.html

There is a function

  (define f
    (lambda (append)
      (define cons (append "ugly" "confusing"))
      (let ([append 'this-was])
        (list append cons))))
  > (f list)
  '(this-was ("ugly" "confusing"))

I see that we define function f, inside we define lambda that takes (append), why ? Procedure (body) for lambda is another function called cons, that appends two strings.

I don't understand this function at all. Thanks !

+5  A: 

The section that you're referring to demonstrates lexical scope in Racket. As in other Scheme implementations, the main point is that you can "shadow" every binding in the language. Unlike most "mainstream" languages, there are no real keywords that are "sacred" in the sense that they can never be shadowed by a local binding.

Note that a really good tool to visualize what is bound where is DrRacket's "check syntax" button: click it, and you'll see your code with highlights that shows which parts are bindings, which are special forms -- and if you hover the mouse over a specific name, you'll see an arrow that tells you where it came from.

Eli Barzilay
Appreciate for pointing out "Check Syntax" button
+3  A: 

Scheme takes some getting used to :)

  1. f is assigned the function returned by the lambda.
  2. lambda defines the function that takes a parameter (called append).
  3. (define cons (append "ugly" "confusing")) is not a function per se, but calls append with the two strings as parameter and assigns the result to cons.
  4. inside the let block, append is re-assigned a different value, the symbol this-was.
  5. the let block creates a list of append (which now contains 'this-was) and cons (which contains '("ugly" "confusing") from 3 above
  6. since 5 is the last statement that value is returned by the whole function which is called f
  7. f is called with the parameter list (the list function). which gets passed as the parameter append. And this is why 3 above creates a list '("ugly" "confusing") which gets assigned to cons.

Hope that cleared up things a bit. Cheers!

Sujoy
What is kind of confusing, is the parameter `list` in `(f list)`. How can we just past `list` as parameter ?
is all lispy languages (scheme included), functions are first class, which means that they can be passed as arguments to other functions, they can be assigned to, so on and so forth. read http://en.wikipedia.org/wiki/First-class_function
Sujoy
Let me explain how I see this `(define f` is function, it's argument is `(lambda (append)...`. So how can we pass the argument, if `(append)` is already "pre-build" as argument of lambda ? Is `list` being channeled through `lambda` at all ?
Or `(f list)` means that `list` would a "wrapper" for `(lambda (append)....)`
`lambda` creates and returns anonymous functions (functions without a name), `define` just takes that anonymous function and names it `f`. Now when you pass `list` to `f`, you are actually passing it to the anonymous `lambda` function, which is what `append` refers to throughout the rest of the code.
Sujoy
The thing is, in the documentation (link in my original question), `append` itself is actually a "function". In other words, in `f` changes meaning of `append` from being a function, to mere argument.
right, the meaning of append changes offcourse. thats what was explained by Eli Barzilay in his answer :)
Sujoy
also that the meaning of append can change is what makes scheme so powerfull, just read up on the function as first class member article
Sujoy
I missed the link. Thank you for helping me out. I will +1 all you responses.
You're welcome :)
Sujoy
You should be careful with saying things like "the meaning of `append` changed" -- it really didn't. (Same goes for using "reassigned".) Instead, just read `(define append ...)` as something that defines a completely new `append`, whose definition applies to the local function only (that's its *lexical scope*). The "real" append -- the function that you normally have bound at the top -- is still there, and still has the same meaning.
Eli Barzilay