I recently started reading SICP and doing the excercies in the book. I installed both mit-scheme on command line and after tinkering with it a bit, I stumbled upon DrRacket and installed the SICP components from http://www.neilvandyke.org/racket-sicp/
everything was working ok until I came to Excercise 1.10 and when i wrote the function as it is written in the book:
(define (A x y)
(cond ((= y 0) 0)
((= x 0) (* 2 y))
((= y 1) 2)
(else (A (- x 1)
(A x (- y 1))))))
and then run the code with cmd + R, then when I call this from the repl such that:
> (A 1 10)
i get the error
A: undefined;
cannot reference an identifier before its definition
However, the same code works on the version installed on the command line.. What is going on here? Is something broken on DrRacket mit-scheme implementation or am i doing something wrong here?
I'm using DrRacket version 6.1.1(m3) on Mac OS X Yosemite
Any help would be greatly appreciated, thanks!
The SICP language tries to make the examples of the book work directly in the language, but there are bugs lurking around. All Scheme versions prior to R6RS are case insensitive, which means you can write this and make it run ok:
(define (test a)
(+ A a)) ; A and a are the same
(TEST 5) ; ==> 10
I believe the author based their work on the #!r5rs
language implementation in Racket, which is the closest living language to version used in the book. It is also case insensitive as SICP. However, it seems the interactions window works different for both languages. It seems like it expect every identifier defined in the definitions window to be named as if it was defined in lower case and that the interactions window is not case insensitive. So you get an error if you move (TEST 5)
to the interactions windows:
> (TEST 5)
. . TEST: undefined;
cannot reference an identifier before its definition
The code and interactions are read by different parser function in the language module parser. Apparently they have made syntax case insensitive, but read is still case sensitive. You can test this by entering (read)
and feed it TeSt
it will print TeSt
and not test
. If you did (define x 'TeSt)
in definitions window and evaluate x
in interactions window it prints test
. Racket makes it case insensitive by changing every identifier to lower case. Since this is both in R5RS and SICP I expect SICP to be based on R5RS and that the bug is inherited. You can fix this in two ways. One is to always use lower case identifiers. You'll follow the convention and it won't hurt when you advance to the case sensitive Scheme reports. The alternative is to add one line anywhere in your definitions window:
(#%require r5rs/init) ; fix interactions window
After you have hit RUN the interactions window is case insensitive as it should be for an early Scheme.
> (TEST 5)
10
>
Happy hacking!