Reputation: 45921
I'm still learning Racket.
I have to call an unknown function. The function and its parameters are in the following list:
(define l1 '((function-name parameter1)
(function-name parameter3)))
To run that function, I'm doing:
(first (car l1)) (second (car l1)) another-parameter
But I get the error:
application: not a procedure;
expected a procedure that can be applied to arguments
given: 'function-name
arguments...:
How can I run that function-name
?
UPDATE:
I have tried Óscar's answer:
(eval (first (car l1)) (second (car l1)) another-parameter)
And I get the error:
eval: arity mismatch;
the expected number of arguments does not match the given number
given: 3
arguments...:
I have also tried:
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
(eval (first (car l1)) (second (car l1)) another-parameter ns)
And I get the same error:
eval: arity mismatch;
the expected number of arguments does not match the given number
given: 4
arguments...:
Then, I tried this:
(eval (list (first (car l1)) (second (car l1)) another-parameter))
And I get the error:
function-name: unbound identifier;
also, no #%app syntax transformer is bound in: function-name
Finally, I have tried:
(eval (list (first (car l1)) (second (car l1)) another-parameter) ns)
And I get an internal error from function-name
. But this function, works perfectly.
function-name
could be at least three functions (or more), this is why I haven't put it here before. All of them will have two lists as parameters, and they will return #t or #f.
One of then, then one is testing now is:
(define match (lambda (list1 list2) ...))
Obviously, list1
and list2
are lists.
UPDATE 2:
I have tried Óscar's Minimal, Complete and verifiable example, and it works. But, I have modified to used on my on work, and it doesn't work. Look:
(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)
I have created another-function
, and it fails with the parameter 'the-parameter
. It complains saying:
the-parameter: undefined;
cannot reference an identifier before its definition
So the problem is when I use a function's parameter as a parameter for the eval
function.
Upvotes: 0
Views: 114
Reputation: 236004
You can use eval
and quasiquoting for this, it works for your input. Do notice that this is how you should post your questions, it's a Minimal, Complete, and Verifiable example that anyone can copy and run, without having to guess what you were thinking:
(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))
Upvotes: 2
Reputation: 48745
Please consider evaluating the procedure like this:
(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
Why does this work? Well. Your attempted to call the name of a procedure. By evaluating the procedure name you get the actual procedure object. You can indeed evaluate a procedure in the REPL and see what you get back:
+ ; ==> #<procedure:+>
l1 ; ==> ((#<procedure:sin> 3) (#<procedure:+> 1 2 3))
If l1
were defined as '((sin (+ 1 2)) (+ 1 2 3))
evaluating it would return ((sin (+ 1 2)) (+ 1 2 3))
so there is a big difference.
And of course. Using the quasiquote/unquote is just a fancy way of writing this:
(define l1 (list (list sin (+ 1 2))
(list + '1 '2 '3)))
Upvotes: 4