我将命令行参数传递给我的Lisp程序,当它们点击我的主函数时,它们的格式如下:
("1 1 1" "dot" "2 2 2")
我有一个点函数(它将两个向量作为参数)并且想直接从参数中调用它,但是这是不可能的,因为像(funcall(second args)...)这样的东西会收到“dot”而不是点作为函数名称。
我尝试过这个功能的变体:
(defun remove-quotes (s)
(setf (aref s 0) '""))
无济于事,才意识到引号不是字符串的一部分。有没有一种简单的方法可以做到这一点,或者我应该检查每个字符串然后调用适当的函数?
答案 0 :(得分:8)
“1 1 1”是一个由五个字符组成的字符串:1,空格,1,空格和1.双引号不是字符串的一部分。
(“1 1 1”“dot”“2 2 2”)是三个字符串的列表。
上面没有“字符。”用于分隔s表达式中的字符串。
如果你有一个点函数,你需要告诉我们它期望什么样的输入数据。 它有两个数字列表吗?然后,您必须将字符串“1 1 1”转换为数字列表。
(with-input-from-string (in "1 1 1")
(loop for data = (read in nil in)
until (eq data in)
collect data)))
要从字符串“dot”获取函数DOT,首先找到符号DOT,然后获取其符号函数。
(symbol-function (find-symbol (string-upcase "dot")))
对于find-symbol,如果符号所在的特殊包中,可能还需要指定包。
将列表转换为向量然后是下一个构建块。
所以你需要将函数的参数转换为向量(可能首先将它们转换为列表,如上所示)。然后你需要找到这个功能(见上文)。如果你有函数和参数,那么你可以使用FUNCALL或APPLY调用函数(无论什么更方便)。
答案 1 :(得分:2)
问题有点不清楚,但据我所知,当你将列表("1 1 1" "dot" "2 2 2")
作为输入来评估表达式(dot "1 1 1" "2 2 2")
时,你想要它。在这种情况下,您可以这样做:
(defun apply-infix (arg1 f arg2)
(apply (intern (string-upcase f)) (list arg1 arg2)))
(defun apply-list-infix (lst)
(apply 'apply-infix lst))
(apply-list-infix '("1 1 1" "dot" "2 2 2"))
答案 2 :(得分:2)
funcall
不接受字符串作为函数指示符。你需要给它一个符号。你可能想做的是:
string-upcase
) intern
)的符号。请注意,如果未根据函数名称所在的包设置*package*
,则需要提供包名称作为intern
的第二个参数。例如(对于包dot
中名为cl-user
的函数:
(funcall (intern (string-upcase "dot") 'cl-user) ...)