Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
467 views
in Technique[技术] by (71.8m points)

scheme - Difference between define, let and set!

Ok, this is a fairly basic question: I am following the SICP videos, and I am a bit confused about the differences between define, let and set!.

1) According to Sussman in the video, define is allowed to attach a value to avariable only once (except when in the REPL), in particular two defines in line are not allowed. Yet Guile happily runs this code

(define a 1)
(define a 2)
(write a)

and outputs 2, as expected. Things are a little bit more complicated because if I try to do this (EDIT: after the above definitions)

(define a (1+ a))

I get an error, while

(set! a (1+ a))

is allowed. Still I don't think that this the only difference between set! and define: what is that I am missing?

2) The difference between define and let puzzles me even more. I know in theory let is used to bind variables in local scope. Still, it seems to me that this works the same with define, for instance I can replace

(define (f x)
    (let ((a 1))
        (+ a x)))

with

(define (g x)
    (define a 1)
    (+ a x))

and f and g work the same: in particular the variable a is unbound outside g as well.

The only way I can see this useful is that let may have a shorter scope that the whole function definition. Still it seems to me that one can always add an anonymous function to create the necessary scope, and invoke it right away, much like one does in javascript. So, what is the real advantage of let?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your confusion is reasonable: 'let' and 'define' both create new bindings. One advantage to 'let' is that its meaning is extraordinarily well-defined; there's absolutely no disagreement between various Scheme systems (incl. Racket) about what plain-old 'let' means.

The 'define' form is a different kettle of fish. Unlike 'let', it doesn't surround the body (region where the binding is valid) with parentheses. Also, it can mean different things at the top level and internally. Different Scheme systems have dramatically different meanings for 'define'. In fact, Racket has recently changed the meaning of 'define' by adding new contexts in which it can occur.

On the other hand, people like 'define'; it has less indentation, and it usually has a "do-what-I-mean" level of scoping allowing natural definitions of recursive and mutually recursive procedures. In fact, I got bitten by this just the other day :).

Finally, 'set!'; like 'let', 'set!' is pretty straightforward: it mutates an existing binding.

FWIW, one way to understand these scopes in DrRacket (if you're using it) is to use the "Check Syntax" button, and then hover over various identifiers to see where they're bound.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...