运行名称在列表中的函数

时间:2019-03-25 18:40:35

标签: list functional-programming scheme racket

我还在学习球拍。

我必须调用一个未知函数。该函数及其参数在以下列表中:

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

很显然,list1list2是列表。

更新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函数的参数时。

2 个答案:

答案 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)

您可以为此使用evalquasiquoting,它可用于您的输入。 要做注意,这就是您应该发布问题的方式,这是一个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))