【问题标题】:Dynamically built functions in LISPLISP 中动态构建的函数
【发布时间】:2016-02-09 07:58:20
【问题描述】:

我有一个关于动态构建函数(或类似函数)的问题。在 Java 中,我可以以编程方式将一些 Source 写入字符串,编译该字符串并像函数一样多次执行它。

想象一下,我有一些遗传算法来创建获取 n 个输入参数的最佳代码,根据基因组计算它们并返回 m 个输出参数。所以我想知道是否有可能(我很确定它是),创建一个列表列表的列表......包含该函数,然后使用不同的输入参数调用该函数数千次以计算错误率.

我现在需要的是一个示例,如何以编程方式创建这样的列表以及如何使用它。目前我完全陷入困境。

热烈欢迎任何参考资料或示例。

【问题讨论】:

  • 您使用的是哪种 Lisp? Common Lisp?
  • Steel Bank Common Lisp
  • 任何 Lisp 初学者的书都会解释如何做到这一点。快速的互联网搜索会找到无数的例子。你可以看说明书。为什么不把你自己的一些精力放在一个基本上微不足道的问题上呢?如果您有任何问题,请出示您的代码,有人会帮助您。如果没有任何代码、任何示例、任何示例应用程序、任何解决问题的尝试,Stackoverflow 并不是一个真正提出问题的地方。请多多努力。
  • 一个单一的参考会很好。
  • 您编写了“编译此函数以提高速度”。为什么不搜索'compile' & 'function' & 'lisp'?谷歌结果集看起来很有希望......

标签: lisp common-lisp metaprogramming


【解决方案1】:

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

好像……

【讨论】:

    【解决方案2】:

    正如 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 表达式,但您也可以使用常规列表操作操作(pushcons 等)来构建它。

    【讨论】:

    • 我刚刚打开这个问题是为了大致写出这个答案。不错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-16
    • 2019-12-07
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    相关资源
    最近更新 更多