views:

481

answers:

4

I'm trying to pass a function as an argument and call that function within another function.

A piece of my code looks like this:

(defun getmove(strategy player board printflag)
(setq move (funcall strategy player board))
(if printflag
    (printboard board))

strategy is passed as a symbol represented in a two dimensional list as something such as 'randomstrategy

I keep getting the error: "FUNCALL: 'RANDOMSTRATEGY is not a function name; try using a symbol instead...

When I replace strategy with 'randomstrategy it works fine. I can also call randomstrategy independently. What is the problem?

+1  A: 

is stategy a variable with a functional value? if not than use #' syntax macro before it. that is #'strategy. or just (if function is global) 'strategy

WHY? because arguments of funcall call evaluted. And your strategy symbol is just a variable name in this case. Variabe this value 'RANDOMSTRATEGY. But you should give to funcall a function. how to access function if we have symbol?

Three cases:

1) Symbol may denote variable with functional value
2) Symbol may denote global function (symbol-function - is the accessor in this case.
3) Symbol may denote local function (flet, labels and so on)

look like you forgot to define RANDOMSTRATEGY function

(defun RANDOMSTRATEGY and so on ...)

Hmm

FUNCALL: 'RANDOMSTRATEGY

may be you have (setq strategy ''RANDOMSTRATEGY)?

then strategy will evaluate to 'RANDOMSTRATEGY. Did you notice ' before symbol name? 'RANDOMSTRATEGY <=> (quote RANDOMSTRATEGY) it is not a proper function name

Trickster
What do you mean?I said I could call it and 'randomstrategy worked fine.Here is the randomstrategy function:(defun randomstrategy(player board)(let*((moves (legalmoves player board)) (r (nth (+ 1(random (- (nth 0 moves) 1))) moves))) r))
Chad
may be there to many quotes?
Trickster
maybe you wrote (setq strategy ''RANDOMSTRATEGY) ?
Trickster
There is no setq for strategy. It is only a function parameter. This isn't a problem isn't it?
Chad
How would I go about stripping that quote(?
Chad
How 'RANDOMSTRATEGY became the value of strategy?
Trickster
A: 

Have you set strategy anywhere? It looks like a scoping issue.

Try this

(setq strategy 'randomstrategy)
(setq move (funcall strategy player board))
Eric Normand
A: 

Not seeing the code, I'm imagining you're doing something like this:

(defun randomstrategy (a b c) ...)

and then doing this:

(getmove 'randomstrategy x y z)

What you want to do is pass the function "randomstrategy" to getmove using #':

(getmove #'randomstrategy x y z)

In CommonLisp, #' yields the function bound to the symbol, which is what you want to pass to getmove.

themis
In Common Lisp, it is perfectly valid to funcall symbols naming global functions.
dmitry_vk
+1  A: 

The problem is that the variable strategy does not contain the symbol randomstrategy but rather the list (!) 'randomstrategy (which is a shorthand notation for (quote randomstrategy)).

Now, you could, of course, extract the symbol from the list by way of the function second, but that would only cover the real problem up, which is probably somewhere up the call chain. Try to determine why the argument that is passed to function getmove is 'randomstrategy, not randomstrategy as it should be. (Maybe you erroneously used a quote inside of a quoted list?)

Oh, and don't let yourself be confused by the fact that (funcall 'randomstrategy ...) works: the expression 'randomstrategy does not, after all, evaluate to itself, but to the symbol randomstrategy.

Matthias Benkard