Common Lisp:funcallに関する初心者の問題
-
06-07-2019 - |
質問
関数を引数として渡し、その関数を別の関数内で呼び出そうとしています。
私のコードの一部は次のようになります:
(defun getmove(strategy player board printflag)
(setq move (funcall strategy player board))
(if printflag
(printboard board))
戦略は、「randomstrategy
」などの2次元リストで表されるシンボルとして渡されますエラーが発生し続けます: <!> quot; FUNCALL: 'RANDOMSTRATEGYは関数名ではありません。代わりにシンボルを使用してみてください...
戦略を「randomstrategy」に置き換えると、うまく機能します。 また、randomstrategyを個別に呼び出すこともできます。 問題は何ですか?
解決
stategyは関数値を持つ変数ですか?前に# '構文マクロを使用しない場合。それが戦略です。または単に(関数がグローバルの場合) '戦略
なぜ? funcall呼び出しの引数が評価されたためです。この場合、戦略シンボルは単なる変数名です。この値を変更します 'RANDOMSTRATEGY。ただし、関数をfuncallに渡す必要があります。シンボルがある場合に関数にアクセスする方法は?
3つのケース:
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)
ランダム関数を定義するのを忘れたように見えます
(defun RANDOMSTRATEGYなど...)
うーん
FUNCALL: 'RANDOMSTRATEGY
お持ちかもしれません(setqストラテジー ''ランダム戦略)?
その後、戦略は 'RANDOMSTRATEGYと評価されます。 シンボル名の前に 'に気づきましたか? 'ランダム戦略<!> lt; = <!> gt; (引用RANDOMSTRATEGY)適切な関数名ではありません
他のヒント
問題は、変数strategy
に記号randomstrategy
ではなく、 list (!)'randomstrategy
((quote randomstrategy)
の略記法)が含まれていることです。
さて、もちろん、できました、関数second
を使用してリストからシンボルを抽出しますが、それは実際の問題をカバーするだけで、おそらく呼び出しのどこかにあります鎖。関数getmove
に渡される引数が(funcall 'randomstrategy ...)
ではなく<=>である理由を判断してください。 (引用リスト内で誤って引用を使用した可能性がありますか?)
ああ、<=>が機能するという事実に混乱しないでください。式<=>は結局のところ、それ自体ではなく、シンボル<=>に対して評価されます。
どこに戦略を設定しましたか?スコープの問題のようです。
これを試してください
(setq strategy 'randomstrategy)
(setq move (funcall strategy player board))
コードが表示されない、私はあなたがこのようなことをしていると想像しています:
(defun randomstrategy(a b c)...)
そしてこれを行う:
(getmove 'randomstrategy x y z)
やりたいことは、関数<!> quot; randomstrategy <!> quot;を渡すことです。 # 'を使用して移動するには:
(getmove# 'randomstrategy x y z)
CommonLispでは、# 'はシンボルにバインドされた関数を生成します。 getmoveに渡すもの。