LISP 中的动态构建函数
Dynamically built functions in LISP
我有一个关于动态构建函数(或类似的东西)的问题。在 Java 中,我可以通过编程将一些 Source 写入字符串,编译该字符串并像函数一样执行它几次。
想象一下,我有一些遗传算法可以创建最佳代码来获取 n 个输入参数,根据基因组计算它们并返回 m 个输出参数。所以我想知道是否有可能(而且我很确定它是),创建一个列表列表的列表....包含该函数,然后用不同的输入参数调用这个函数几千次来计算错误率.
我现在需要的是一个示例,说明如何以编程方式创建这样的列表以及如何使用它。目前我完全卡住了。
热烈欢迎任何参考或示例。
正如 Rainer Joswig 所说,您应该阅读一些 Lisp 书籍(特别是关于列表操作和宏的章节),但这里有一个使用 compile
:
的非常简单的示例
(defun test (op number)
(let ((func (compile nil `(lambda (y)
(,op y y)))))
(format t "The function is ~:[not compiled~;compiled~].~%"
(compiled-function-p func))
(funcall func number)))
(test '+ 5) ; => 10
(test '* 5) ; => 25
这使用 backquote 语法构造 lambda
表达式,但您也可以使用常规列表操作操作(push
、cons
等)构建它.
Lisp 代码是数据:列表、符号、数字……
(defun foo () 42)
Lisp 具有 list
和 +
等功能。你可以使用它:
(list 'defun
'foo
'()
(+ 25 17))
如何编译一个函数?评估代码并编译它。
(compile (eval my-function-definition))
所以放在一起:
CL-USER 10 > (compile (eval (list 'defun 'foo '() (+ 25 17))))
FOO
NIL
NIL
CL-USER 11 > (foo)
42
真的编译了吗?
CL-USER 11 > (disassemble 'foo)
424000EA3C:
0: 49396275 cmpq [r10+75], rsp
4: 7720 ja L1
6: 4883F900 cmpq rcx, 0
10: 751A jne L1
12: 4157 push r15
14: 55 push rbp
15: 4889E5 moveq rbp, rsp
18: 4989DF moveq r15, rbx
21: BF50010000 move edi, 150
26: B901000000 move ecx, 1
31: 4889EC moveq rsp, rbp
34: 5D pop rbp
35: 415F pop r15
37: C3 ret
L1: 38: 41FFA6E7020000 jmp [r14+2E7] ; SYSTEM::*%WRONG-NUMBER-OF-ARGUMENTS-STUB
45: 90 nop
46: 90 nop
47: 90 nop
48: 90 nop
49: 90 nop
50: 90 nop
51: 90 nop
好像是...
我有一个关于动态构建函数(或类似的东西)的问题。在 Java 中,我可以通过编程将一些 Source 写入字符串,编译该字符串并像函数一样执行它几次。
想象一下,我有一些遗传算法可以创建最佳代码来获取 n 个输入参数,根据基因组计算它们并返回 m 个输出参数。所以我想知道是否有可能(而且我很确定它是),创建一个列表列表的列表....包含该函数,然后用不同的输入参数调用这个函数几千次来计算错误率.
我现在需要的是一个示例,说明如何以编程方式创建这样的列表以及如何使用它。目前我完全卡住了。
热烈欢迎任何参考或示例。
正如 Rainer Joswig 所说,您应该阅读一些 Lisp 书籍(特别是关于列表操作和宏的章节),但这里有一个使用 compile
:
(defun test (op number)
(let ((func (compile nil `(lambda (y)
(,op y y)))))
(format t "The function is ~:[not compiled~;compiled~].~%"
(compiled-function-p func))
(funcall func number)))
(test '+ 5) ; => 10
(test '* 5) ; => 25
这使用 backquote 语法构造 lambda
表达式,但您也可以使用常规列表操作操作(push
、cons
等)构建它.
Lisp 代码是数据:列表、符号、数字……
(defun foo () 42)
Lisp 具有 list
和 +
等功能。你可以使用它:
(list 'defun
'foo
'()
(+ 25 17))
如何编译一个函数?评估代码并编译它。
(compile (eval my-function-definition))
所以放在一起:
CL-USER 10 > (compile (eval (list 'defun 'foo '() (+ 25 17))))
FOO
NIL
NIL
CL-USER 11 > (foo)
42
真的编译了吗?
CL-USER 11 > (disassemble 'foo)
424000EA3C:
0: 49396275 cmpq [r10+75], rsp
4: 7720 ja L1
6: 4883F900 cmpq rcx, 0
10: 751A jne L1
12: 4157 push r15
14: 55 push rbp
15: 4889E5 moveq rbp, rsp
18: 4989DF moveq r15, rbx
21: BF50010000 move edi, 150
26: B901000000 move ecx, 1
31: 4889EC moveq rsp, rbp
34: 5D pop rbp
35: 415F pop r15
37: C3 ret
L1: 38: 41FFA6E7020000 jmp [r14+2E7] ; SYSTEM::*%WRONG-NUMBER-OF-ARGUMENTS-STUB
45: 90 nop
46: 90 nop
47: 90 nop
48: 90 nop
49: 90 nop
50: 90 nop
51: 90 nop
好像是...