为什么这个方案函数正确运行然后产生“非法函数”错误?

时间:2021-06-13 15:43:24

I'm attempting to write a scheme function that prints each entry of a list on a new line. This function and sample input works as expected, then gives an "illegal function" error and exits. I'm using tinyscheme from the debian repos.

我正在尝试编写一个方案函数,在新行上打印列表的每个条目。此函数和样本输入按预期工作,然后出现“非法函数”错误并退出。我正在使用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 个解决方案

#1


A parenthesis followed by an expression means function application.

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

(expr1 expr2 ...)

Means evaluate expr1, expr2, .... Then apply the result of expr1 to the result of expr2 ... . If the result of expr1 is not a function, then you'll see the "illegal function" error.

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

The fix is as leppie states to add a begin:

修复就像leppie状态一样添加一个开头:

(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) )

Here (begin expr1 expr2 ....) means evalute expr1, expr2, ... in order. Finally return the value of the last expression.

这里(begin expr1 expr2 ....)表示依次为evalute expr1,expr2,....最后返回最后一个表达式的值。

#2


Block Structure

In scheme, the branches of the if special form do not have an implicit block structure. As Soegaard suggests, begin may be used. Or you can use cond to create a block—in which case, expanding to more than two branches comes along for free.

在方案中,if特殊形式的分支没有隐式块结构。正如Soegaard所说,开始可能会被使用。或者你可以使用cond创建一个块 - 在这种情况下,扩展到两个以上的分支免费提供。

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

Problem with Return Type

Note that print-list is problematic because it returns...well something undefined. For example in MIT Scheme:

请注意,print-list是有问题的,因为它返回...好的东西未定义。例如在麻省理工学院计划中:

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

Or in Gauche Scheme:

或者在Gauche Scheme中:

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

While in Racket's implementation of R5RS the return value is not printed.

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

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

Returning a Value

One common approach to signalling the end of a series of side effects is to return a value. null is one possibility. A symbol is another.

发信号通知一系列副作用结束的一种常见方法是返回一个值。 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)))))

Calling it now will in a Scheme REPL removes the problematic return value:

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

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

#1


A parenthesis followed by an expression means function application.

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

(expr1 expr2 ...)

Means evaluate expr1, expr2, .... Then apply the result of expr1 to the result of expr2 ... . If the result of expr1 is not a function, then you'll see the "illegal function" error.

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

The fix is as leppie states to add a begin:

修复就像leppie状态一样添加一个开头:

(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) )

Here (begin expr1 expr2 ....) means evalute expr1, expr2, ... in order. Finally return the value of the last expression.

这里(begin expr1 expr2 ....)表示依次为evalute expr1,expr2,....最后返回最后一个表达式的值。

#2


Block Structure

In scheme, the branches of the if special form do not have an implicit block structure. As Soegaard suggests, begin may be used. Or you can use cond to create a block—in which case, expanding to more than two branches comes along for free.

在方案中,if特殊形式的分支没有隐式块结构。正如Soegaard所说,开始可能会被使用。或者你可以使用cond创建一个块 - 在这种情况下,扩展到两个以上的分支免费提供。

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

Problem with Return Type

Note that print-list is problematic because it returns...well something undefined. For example in MIT Scheme:

请注意,print-list是有问题的,因为它返回...好的东西未定义。例如在麻省理工学院计划中:

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

Or in Gauche Scheme:

或者在Gauche Scheme中:

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

While in Racket's implementation of R5RS the return value is not printed.

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

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

Returning a Value

One common approach to signalling the end of a series of side effects is to return a value. null is one possibility. A symbol is another.

发信号通知一系列副作用结束的一种常见方法是返回一个值。 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)))))

Calling it now will in a Scheme REPL removes the problematic return value:

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

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