Function 如何在方案中重新创建应用程序

Function 如何在方案中重新创建应用程序,function,recursion,scheme,lisp,apply,Function,Recursion,Scheme,Lisp,Apply,如何在scheme中创建函数apply? 一个my apply函数,它执行与它相同的操作 (define (my-apply fn lst) (if (null? lst) 我不知道从这里走到哪里,也不知道如何开始。我认为apply比eval更基本,因此以下是作弊: (define (my-apply func args) (eval `(,func ,@args))) 我认为没有eval你就无法做到这一点,我认为apply比eval更基本,因此以下是作弊: (define (my-

如何在scheme中创建函数apply? 一个my apply函数,它执行与它相同的操作

 (define (my-apply fn lst)
 (if (null? lst)

我不知道从这里走到哪里,也不知道如何开始。

我认为
apply
eval
更基本,因此以下是作弊:

(define (my-apply func args)
  (eval `(,func ,@args)))

我认为没有
eval

你就无法做到这一点,我认为
apply
eval
更基本,因此以下是作弊:

(define (my-apply func args)
  (eval `(,func ,@args)))
(define (my-apply proc args)
  (define (q v)
    (list 'quote v))
  (eval (cons proc (map q args))))

我认为如果没有
eval

你就做不到。我不久前创建了一个lisp解释器,它有
eval
和宏,但它没有
apply
。我想知道是否有办法让我的解释器支持
apply
,所以我尝试了一下。这是我的第一次尝试:

(define (my-apply proc args) 
  (eval (cons proc args)))
(define (my-apply proc args)
  (define (q v)
    (list 'quote v))
  (eval (cons proc (map q args))))
这显然不起作用,因为函数和参数列表会被计算两次。例如,
(我的应用cons'(ab))
将为您提供
(cons ab)
,而不是
(cons'a'b)
。然后我认为这可能是一个宏的工作,但放弃了这个想法,因为参数列表在宏扩展时是未知的。程序必须是这样的,所以我想我可以在将列表传递给
eval
之前引用它

(define (my-apply proc args)
  (define (q v)
    (list 'quote v))
  (eval (cons proc (map q args))))
这实际上是可行的,但这比本机
apply
撤销作业
eval
所做的工作要多得多


如果你不被允许使用
eval
你真是倒霉透了。这是不可能做到的。不使用
apply
来实现
eval
也是如此,因为这样您就无法执行原语

我不久前创建了一个lisp解释器,它有
eval
和宏,但没有
apply
。我想知道是否有办法让我的解释器支持
apply
,所以我尝试了一下。这是我的第一次尝试:

(define (my-apply proc args) 
  (eval (cons proc args)))
(define (my-two-arg-apply f a)
  (let ((l (length a)))
    (cond ((= l 0) (f))
          ((= l 1) (f (car a)))
          ((= l 2) (f (car a) (cadr a))
          ...
          ((= l 5) (f (car a) (cadr a) ... (caddddr a)))
          ...
          ((= l 7) (f (car a) (cadr a) ... (caddddr a)
                      (list-ref a 5) (list-ref a 6)))
          ... ;; lots more cases
          (else (error "argument passing limit exceeded")))))
这显然不起作用,因为函数和参数列表会被计算两次。例如,
(我的应用cons'(ab))
将为您提供
(cons ab)
,而不是
(cons'a'b)
。然后我认为这可能是一个宏的工作,但放弃了这个想法,因为参数列表在宏扩展时是未知的。程序必须是这样的,所以我想我可以在将列表传递给
eval
之前引用它

(define (my-apply proc args)
  (define (q v)
    (list 'quote v))
  (eval (cons proc (map q args))))
这实际上是可行的,但这比本机
apply
撤销作业
eval
所做的工作要多得多

如果你不被允许使用
eval
你真是倒霉透了。这是不可能做到的。不使用
apply
来实现
eval
也是如此,因为这样您就无法执行原语

(define (my-two-arg-apply f a)
  (let ((l (length a)))
    (cond ((= l 0) (f))
          ((= l 1) (f (car a)))
          ((= l 2) (f (car a) (cadr a))
          ...
          ((= l 5) (f (car a) (cadr a) ... (caddddr a)))
          ...
          ((= l 7) (f (car a) (cadr a) ... (caddddr a)
                      (list-ref a 5) (list-ref a 6)))
          ... ;; lots more cases
          (else (error "argument passing limit exceeded")))))
宏可以用来生成所需的大量代码

在R6RS中引入了
错误。令人惊讶的是,在此之前,Scheme程序没有合理的方法报告错误

甚至不要考虑制作一个
pop
宏并使用模式
(f(pop a)(pop a)…(pop a))
;Scheme没有定义函数参数的求值顺序,这与其他一些Lisp方言(如ANSI CL)不同

宏可以用来生成所需的大量代码

在R6RS中引入了
错误。令人惊讶的是,在此之前,Scheme程序没有合理的方法报告错误


甚至不要考虑制作一个
pop
宏并使用模式
(f(pop a)(pop a)…(pop a))
;Scheme没有定义函数参数的求值顺序,这与其他一些Lisp方言(如ANSI CL)不同。

您可以使用什么?所有纯函数构造,以及自我实现以来的映射。如果您可以使用
eval
,任务就很简单;-)我认为我做不到:(那么我认为你不能实现
apply
。你可以使用什么?所有纯函数结构,以及自我实现以来的映射。如果你可以使用
eval
,任务很简单;-)我认为我做不到:(那么我认为你不能实现
apply