代码之家  ›  专栏  ›  技术社区  ›  Thunfische

Lisp-将所有元素增加一个数

  •  1
  • Thunfische  · 技术社区  · 7 年前

        (defparameter a 1)
        (defun foo (x)
            (+ x 1))
        (foo a)
        (print a)
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   Gwang-Jin Kim    7 年前

    我想,你想知道的其实是:

    (defparameter a 1)
    
    (defmacro foo (x)
      `(setf ,x (+ ,x 1)))  ;; this macro takes the variable given for x
                            ;; accesses its memory location using `setf`
                            ;; and changes its value  to 2
                            ;; by increasing the accessed value by 1
    (foo a)                 ;; a's value becomes 2 
    a                       ;; 2
    

    A.虽然我不想给你带来口齿不清的快乐。:)

    foo = incf

    但是 (将给定值增加1) 正是 incf公司 在CommonLisp中,因为通常需要增加1。所以对于这个非常特殊的情况,你可以使用 incf公司

    (defparameter a 1)
    a ;; => 1
    
    (incf a)  ;; incf mutates a to 2 - in exactly the way foo does
    
    a ;; => 2 ;; a ist after that changed.
    

    注意,还有 decf incf公司 .

    但是对于全局变量,可以使用非常正常的 defparameter 将值重新分配给 a :

    (defparameter a 1)
    
    (defparameter a (foo a))  ;; reassigns new value `2` to `a`
    
    a ;; returns 2, since mutated now
    

    对第一个版本的评论:

    (setf <var> <new-value>) A. <new-value> . 所以在Lisp中,必须使用 defmacro setf

    但您已经从Python或C中了解到,通过引用调用会引起多么意想不到的副作用。由于性能原因,Python在默认情况下是按引用调用的(因为Python是经过解释的,如果每次调用函数时都按值调用,则会变得非常慢)。但是使用Lisp,你是/你可以至少在任何时候你想要比解释的Python快的数量级(好吧,我正在简化-Python当然可以调用C函数也可以是超快速的-但是,纯Python当然会比编译的Lisp慢数量级)。你有很多其他的可能性来编程同样的东西。T

    是的)。它产生2,但离开 相同的。对这样的程序进行推理对大脑更为友好,因此在许多情况下可以避免可避免的错误。FP绝对是你应该学习的东西,当你处理Lisp顺便说一句。FP是许多其他概念中的东西,当你学习Lisp-我不想错过它。

    破坏性函数只有在状态确实不可避免和需要时才有意义,特别是在性能很重要的情况下。

        2
  •  6
  •   Kaz    7 年前

    T这两个变量 a 也不是 x 会发生变异。

    函数 foo 1 .

    请注意 ,这对 .

    在ANSI Lisp中,数字不是可变对象;如果我们增加一个变量 (incf x) 现在发生的是 (+ 1 x)

    ANSI Lisp函数参数使用“传递值”,就像大多数主要的Lisp方言一样。什么时候? (foo a) 调用时,参数表达式 减少到一个值:它产生值 1. A. . 在函数中,一个新变量 是本地函数的实例化;这将接收参数值的副本:用 1 与此无关