Here's the relevant link to the R5RS specification explaining the behavior of internal definitions. Notice that in section §5.2.2 is stated that:
... it must be possible to evaluate each
<expression>
of every internal definition in a<body>
without assigning or referring to the value of any<variable>
being defined.
In other words, you can't count on a correct behavior if you define
values that depend on previously define
d values within the same internal definition. Use let*
for this:
(define (quadr x y)
(let* ((xx (* x x))
(yy (* y y))
(xxyy (* xx yy)))
(+ xx yy xxyy)))
Or a bit more verbose, using a couple of nested let
s:
(define (quadr x y)
(let ((xx (* x x))
(yy (* y y)))
(let ((xxyy (* xx yy)))
(+ xx yy xxyy))))
It's very peculiar that inserting a (newline)
causes the variable definition to work for this example, but when you're dealing with undefined behavior, anything can happen. As a side note, if I use #lang racket
instead of #lang r5rs
, the original code works for me without the extra (newline)
.