nil
isn't a Scheme report defined top level binding today. If it exists in an implementation it can be any value so you cannot depend on it. SICP used a earlier version of Scheme than R4RS and thus no modern implementations today will support it fully. I use DrRacket since it supports many of the report languages, has a nice debugger and IDE, and the chances of syntax errors is lessened by the fact it indents the code while writing. It has a SICP compatibilty language so that SICP code works without having to jump through too many hoops.
Historically Scheme came from Lisp and Lisp doesn't differentiate between the empty list and false value. Scheme introduced #t
and #f
but kept the fact that the empty list was considered false until they changed it so that only #f
is false and everything else is considered truthy. nil
was a binding for ()
in early reports so it might be that SCM changed it to #f
when they did the change since CL often use nil
for the false value and ()
for the empty list, even though they are just two representations of the same value.
Lots of implementations introduce their own bindings on top of the report they are compliant with. Using them locks you in to their flavor so the best is to keep the code standard. DrRacket interprets the reports in a very strict manner than other implementations such that a R6RS program written in DrRacket most likely will run without changes in other R6RS compliant implementations. Standards are cool that way!