我有以下代码:
(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)
根据手册我的代码找不到任何问题,搜索时谷歌没有任何问题,但是当我运行代码时,SCM(我选择的方案解释器)给出了以下错误:
;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)
但是当我让我的代码看起来像这样时,它运行正常:
(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)
为什么当我尝试将返回的get作为返回的get-fields列表返回时,我得到一个未绑定的变量错误,但是当我将alfa定义为返回的get-data列表时(在第二个代码块中),它运作正常吗?是get-fields是递归的吗?我不明白。这里的任何答案都很棒,谢谢。
答案 0 :(得分:6)
允许实现使用两种可能的语义之一实现内部define
:letrec
和letrec*
。
SCM显然选择使用letrec
语义。这意味着,给定一堆内部define
,它们都不能立即引用同一束中另一个内部define
的值:适用于letrec
的相同限制。
某些实现(如Racket)使用letrec*
语义。这意味着早期内部define
中定义的任何变量都可以由后来的内部define
直接使用。 (换句话说,您的代码可以在任何基于letrec*
的实现中正常工作。)
由于您使用的是基于letrec
的实现,请执行以下操作:
(let ((returned (get-fields)))
(close-input-port port)
returned)