Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Debug my scheme program please!

Name: Anonymous 2012-01-18 17:21

http://pastebin.com/bUtFTjMH

Sisc (my scheme interpreter) is telling me that
(ContainsDuplicates n) and
(MakeListFromKeys l)

are not procedures. Gives me the error "Attempt to apply non-procedure '#!void'"

Name: Anonymous 2012-01-18 21:11

>>8
Short answer: Different letrec semantics. R5RS letrec is ``broken'', R6RS and Racket fixed it.
Long answer: Internal definitions are equivalent to letrec:
(lambda ()
  (define x y) ...
  body ...)
; =>
(lambda ()
  (letrec ((x y) ...)
    body ...))


R5RS' letrec has unspecified evaluation order like let, binding expressions can refer to the bindings, but cannot depend on them (evaluating them is an error).
So, this code:
(letrec ((x 1) (y (lambda () (+ x 1)))) (y))
evaluates to 2.
This code:
(letrec ((x 1) (y (+ x 1))) y)
is invalid R5RS. A strict implementation should reject this code the same way it rejects (let ((x 1) (x 2)) x).

Racket's letrec is really R6RS' letrec*, which has sequential evaluation order like let*. Binding expressions can depend to previous bindings, and (letrec* ((x 1) (y (+ x 1))) y) returns 2 as you'd expect.
(letrec* ((x x)) x) and (letrec* ((x y) (y 1)) x) still blow up, as they should.

letrec* exists to fix internal definition semantics to match top-level definitions, because people found letrec semantics confusing.
Racket ditched R5RS' letrec altogether and renamed letrec* to letrec, and here we are.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List