代码之家  ›  专栏  ›  技术社区  ›  Paul Nathan

let*和set之间的区别?在公共Lisp中

  •  3
  • Paul Nathan  · 技术社区  · 14 年前

    我正在做一个基因编程爱好项目。

    我有一个函数/宏设置,当以setq/setf形式计算时,它将生成一个类似这样的列表。

    (setq trees (make-trees 2)) 
    ==> (+ x (abs x))
    

    然后它将被绑定到一个lambda函数 #<FUNCTION :LAMBDA (X) ... > 通过战略性地使用函数/宏

    但是,我想用它比手动分配变量更有效一些,所以我写了如下内容:

    (setq sample 
          (let* ((trees (make-trees 2))
             (tree-bindings (bind-trees trees))
             (evaluated-trees (eval-fitness tree-bindings))))
          (list (trees tree-bindings evaluated-trees)))
    

    EVAL: trees has no value 当我把这个放在一个let表格里。我的怀疑是,与SETF相比,宏扩展并没有在LET中完全执行,但这对我来说毫无意义。

    ---编辑:拉我的代码,把整个文件在一个粘贴箱---

    假设我决定setq不会为我做这件事,我写了一个简单的函数:

    (让((树枝(做树2))) (let((求值树(求值适应度树绑定)))

    我有理由肯定我已经完全冲洗了我的宏。 http://pastebin.org/673619

    1 回复  |  直到 14 年前
        1
  •  3
  •   Svante    14 年前

    (Setq make-trees 2) 设置变量的值 make-trees 到2,然后返回2。

    造树 创建一个可以解释为程序的随机树?把它定义为一个函数 defun . 我在想这样的事情:

    (defun make-tree (node-number)
      (if (= node-number 1)
          (make-leaf)
          (cons (get-random-operator)
                (mapcar #'make-tree
                        (random-partition (- node-number 1)))))) 
    

    Let setq 做完全不同的事情。 Setq 为现有变量赋值,而 let

    我认为您应该提供更多的代码;目前,您的问题没有什么意义。


    更新:

    我将修复代码段的缩进以使事情更清楚:

    (setq sample 
          (let* ((trees (make-trees 2))
                 (tree-bindings (bind-trees trees))
                 (evaluated-trees (eval-fitness tree-bindings))))
          (list (trees tree-bindings evaluated-trees)))
    

    let* 建立词汇绑定。这些 仅在其主体范围内:

    (setq sample 
          (let* ((trees (make-trees 2))
                 (tree-bindings (bind-trees trees))
                 (evaluated-trees (eval-fitness tree-bindings)))
            ;; here trees, tree-bindings, and evaluated-trees are bound
            ) ; end of let* body
          ;; here trees, tree-bindings, and evaluated trees are not in scope anymore
          (list (trees tree-bindings evaluated-trees)))
    

    返回一个元素的列表,这将是计算的结果 函数 trees tree-bindings evaluated-trees 论据。

    (setq sample 
          (let* ((trees (make-trees 2))
                 (tree-bindings (bind-trees trees))
                 (evaluated-trees (eval-fitness tree-bindings)))
            (list trees tree-bindings evaluated-trees)))
    

    另一个更新:

    下面是一些可能对您有所帮助的代码:

    (defun make-tree-lambda (depth)
      (list 'lambda '(x)
            (new-tree depth)))
    
    (defun make-tree-function (lambda-tree)
      (eval lambda-tree))
    
    (defun eval-fitness (lambda-form-list input-output-list)
      "Determines how well the lambda forms approach the wanted function
    by comparing their output with the wanted output in the supplied test
    cases.  Returns a list of mean quadratic error sums."
      (mapcar (lambda (lambda-form)
                (let* ((actual-results (mapcar (make-tree-function lambda-form)
                                               (mapcar #'first input-output-list)))
                       (differences (mapcar #'-
                                            actual-results
                                            (mapcar #'second input-output-list)))
                       (squared-differences (mapcar #'square
                                                    differences)))
                  (/ (reduce #'+ squared-differences)
                     (length squared-differences))))
              lambda-form-list))
    
    (defun tree-fitness (tree-list input-output-list)
      "Creates a list of lists, each inner list is (tree fitness). Input
    is a list of trees, and a list of test cases."
      (mapcar (lambda (tree fitness)
                (list tree fitness))
              tree-list
              (eval-fitness (mapcar #'make-tree-lambda tree-list)
                            input-output-list)))