为什么这个方案功能正确运行然后产生一个"非法功能"错误?

时间:2015-05-04 08:45:26

标签: scheme

我试图编写一个方案函数,在新行上打印列表的每个条目。此函数和样本输入按预期工作,然后给出"非法函数"错误并退出。我正在使用debian回购中的tinyscheme。

(define print-list
  (lambda (l)
    (if (null? l)
      (display "done\n")
      (  
         (display (car l))  
         (newline)  
         (print-list (cdr l))  
      )
    )
  )
)
(print-list '(1 2 3 4 5) )

2 个答案:

答案 0 :(得分:5)

括号后跟表达式表示函数应用程序。

(expr1 expr2 ...)

表示评估expr1expr2,....然后将expr1的结果应用于expr2的结果....如果expr1的结果不是函数,那么您将看到“非法函数”错误。

修复与leppie状态一样,添加begin

(define print-list
  (lambda (l)
    (if (null? l)
      (display "done\n")
      (begin  
         (display (car l))  
         (newline)  
         (print-list (cdr l))))))
(print-list '(1 2 3 4 5) )

下面     (开始expr1 expr2 ....) 表示按顺序评估expr1expr2,...最后返回最后一个表达式的值。

答案 1 :(得分:2)

块结构

在方案中,if特殊表单的分支没有隐式block structure。正如Soegaard所说,begin可能会被使用。或者您可以使用cond创建一个块 - 在这种情况下,可以免费扩展到两个以上的分支。

(define (print-list a-list)
  (cond ((null? a-list)(display "done\n"))
    (else
     (display (car a-list))
     (newline)
     (print-list (cdr a-list)))))

返回类型问题

请注意print-list是有问题的,因为它会返回...未定义的内容。例如在MIT Scheme:

1 ]=> (print-list '(a b c))
a
b
c
done
;Unspecified return value

或在Gauche Scheme中:

gosh> (print-list '(a b c))
a
b
c
done
#<undef>

在Racket的R5RS实现中,不会打印返回值。

> (print-list '(a b c))
a
b
c
done

返回值

表示一系列副作用结束的一种常见方法是返回一个值。 null是一种可能性。符号是另一个符号。

(define (print-list a-list)
  (cond ((null? a-list) 'done) ; changed this line.
    (else
     (display (car a-list))
     (newline)
     (print-list (cdr a-list)))))

现在调用它将在一个Scheme REPL中删除有问题的返回值:

gosh> (print-list '(a b c))
a
b
c
done