I have the following code:
(define (get-data)
(define port (open-input-file "../data/problem11.txt"))
(define field 0)
(define (get-fields)
(define field (read port))
(cond ((not (eof-object? field))
(cons field (get-fields)))
(else '())))
(define returned (get-fields))
(close-input-port port)
returned)
(get-data)
I can’t find any problem with my code according to the manuals, and nothing comes up on google when searched, but when I run the code, SCM (my chosen scheme interpreter) gives me the following error:
;ERROR: "/usr/lib/scm/Iedline.scm": unbound variable: get-fields
; in expression: (get-fields)
; in scope:
; (returned get-fields field port . #@define)
; () procedure get-data
;STACK TRACE
1; (#@define ((returned (get-fields)) (get-fields (#@lambda () (# ...
2; (#@get-data)
But when I make my code look like this, it works fine:
(define (get-data port)
(define field 0)
(define (get-fields)
(define field (read port))
(cond ((not (eof-object? field))
(cons field (get-fields)))
(else '())))
(get-fields))
(define port (open-input-file "../data/problem11.txt"))
(define alfa (get-data port))
(close-input-port port)
Why is it that when I attempt to define returned as the returned list of get-fields that I get an unbound variable error, but when I define alfa as the returned list of get-data (in the second code block), it works okay? Is it that get-fields is recursive? I don’t get it. Any answers here would be awesome, thanks.
Implementations are allowed to implement internal
defines using one of two possible semantics:letrecandletrec*.SCM has obviously chosen to use
letrecsemantics. That means that, given a bunch of internaldefines, none of them can immediately refer to the value of another internaldefinein that same bunch: the same restriction that applies toletrec.Some implementations, like Racket, use
letrec*semantics. That means that any variable defined in an earlier internaldefinecan be used directly by later internaldefines. (In other words, your code will work fine in anyletrec*-based implementation.)Since you’re using a
letrec-based implementation, do this: