我还在学习球拍。
我必须调用一个未知函数。该函数及其参数在以下列表中:
(define l1 '((function-name parameter1)
(function-name parameter3)))
要运行该功能,我正在做
(first (car l1)) (second (car l1)) another-parameter
但是我得到了错误:
application: not a procedure;
expected a procedure that can be applied to arguments
given: 'function-name
arguments...:
我该如何运行function-name
?
更新:
我尝试过奥斯卡的答案:
(eval (first (car l1)) (second (car l1)) another-parameter)
我得到了错误:
eval: arity mismatch;
the expected number of arguments does not match the given number
given: 3
arguments...:
我也尝试过:
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
(eval (first (car l1)) (second (car l1)) another-parameter ns)
我得到同样的错误:
eval: arity mismatch;
the expected number of arguments does not match the given number
given: 4
arguments...:
然后,我尝试了此操作:
(eval (list (first (car l1)) (second (car l1)) another-parameter))
我得到了错误:
function-name: unbound identifier;
also, no #%app syntax transformer is bound in: function-name
最后,我尝试了:
(eval (list (first (car l1)) (second (car l1)) another-parameter) ns)
我从function-name
收到内部错误。但是此功能可以正常工作。
function-name
至少可以是三个函数(或更多),这就是为什么我以前没有在这里提到它。它们都将有两个列表作为参数,并且它们将返回#t或#f。
然后是其中一个,现在正在测试:
(define match (lambda (list1 list2) ...))
很显然,list1
和list2
是列表。
更新2:
我已经尝试过Óscar的最小,完整和可验证的示例,并且它可以正常工作。但是,我已经修改为可以在工作中使用,但它不起作用。看:
(define function-name
(lambda (list1 list2)
(append list1 list2)))
(define parameter1 '(1 2))
(define parameter3 '(3 4))
(define another-parameter '(5 6))
(define l1 '((function-name parameter1)
(function-name parameter3)))
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
(define another-function
(lambda (l1 the-parameter)
(cond
[(eval (list (first (car l1)) (second (car l1)) 'the-parameter) ns) l1])
)
)
(another-function l1 another-parameter)
我已经创建了another-function
,但由于参数'the-parameter
而失败。它抱怨说:
the-parameter: undefined;
cannot reference an identifier before its definition
问题是当我使用函数的参数作为eval
函数的参数时。
答案 0 :(得分:4)
请考虑评估以下过程:
(define l1 `((,sin ,(+ 1 2))
(,+ 1 2 3)))
(sin (+ 1 2)) ; ==> 0.14..
((caar l1) (cadar l1)) ; ==> 0.14..
(apply (caar l1) (cdar l1)) ; ==> 0.14..
(+ 1 2 3) ; ==> 6
(apply (caadr l1) (cdadr l1)) ; ==> 6
为什么这样做?好。您试图调用过程的名称。通过评估过程名称,您可以获得实际的过程对象。您确实可以在REPL中评估一个过程,然后看看您得到了什么:
+ ; ==> #<procedure:+>
l1 ; ==> ((#<procedure:sin> 3) (#<procedure:+> 1 2 3))
如果将l1
定义为'((sin (+ 1 2)) (+ 1 2 3))
,则求值将返回((sin (+ 1 2)) (+ 1 2 3))
,因此存在很大差异。
当然。使用准引用/取消引用只是一种写这篇文章的奇特方法:
(define l1 (list (list sin (+ 1 2))
(list + '1 '2 '3)))
答案 1 :(得分:2)
您可以为此使用eval
和quasiquoting,它可用于您的输入。 要做注意,这就是您应该发布问题的方式,这是一个Minimal, Complete, and Verifiable example,任何人都可以复制并运行,而不必猜测您的想法:
(define function-name
(lambda (list1 list2)
(append list1 list2)))
(define parameter1 '(1 2))
(define parameter3 '(3 4))
(define another-parameter '(5 6))
(define l1 '((function-name parameter1)
(function-name parameter3)))
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
(define another-function
(lambda (l1 the-parameter)
(cond
[(eval `(,(first (car l1)) ,(second (car l1)) ',the-parameter) ns)
l1])))
(another-function l1 another-parameter)
=> '((function-name parameter1) (function-name parameter3))