Function 如何在方案中重新创建应用程序
如何在scheme中创建函数apply? 一个my apply函数,它执行与它相同的操作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-
(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
。