lisp初体验-Practical Common Lisp笔记-8.变量
原本以为这章很好理解,结果..杯具了。
在lisp中,变量分为两种:词汇变量(lexical),动态变量(dynamic)。#感觉很别扭,估计我翻坏了,虽然与其他语言做了类比,相当于:局部变量和全局变量。可是看了后面,似乎不是这么个回事啊。如果有资深lisper能够给出这两个变量的专业名称(中文),那真是不胜感激了。目前,好吧,就姑且从字面上来称呼这两种变量吧。
作为变量的基本要素之一就是,变量可以持有一个值。而在Lisp中,甚至无所谓值的类型。很爽,但也会有麻烦:只有到了编译的时候才会发现这方面的错误。
最常见的定义变量方式之一:
(defun foo (x y z) (+ x y z))
(let (variable*) body-form*)(let ((x 10) (y 20) z) ...)
(defun foo (x) (format t "Parameter: ~a~%" x) ; |<------ x is argument (let ((x 2)) ; | (format t "Outer LET: ~a~%" x) ; | |<---- x is 2 (let ((x 3)) ; | | (format t "Inner LET: ~a~%" x)) ; | | |<-- x is 3 (format t "Outer LET: ~a~%" x)) ; | | (format t "Parameter: ~a~%" x)) ; |
(let* ((x 10) (y (+ x 10))) (list x y)) ;这是可以的(let ((x 10) (y (+ x 10))) (list x y)) ;这是不行的(let ((x 10)) (let ((y (+ x 10))) (list x y))) ;这样也是可以的,与第一种等价
(let ((count 0)) #'(lambda () (setf count (1+ count))))
(defparameter *fn* (let ((count 0)) #'(lambda () (setf count (1+ count)))))
(funcall *fn*)1(funcall *fn*)2(funcall *fn*)3
(defvar *count* 0 "Count of widgets made so far.")(defparameter *gap-tolerance* 0.001 "Tolerance to be allowed in widget gaps.")
(defun increment-widget-count () (incf *count*))
(defvar *x* 10)(defun foo () (format t "X: ~d~%" *x*))(foo)X: 10NIL(let ((*x* 20)) (foo))X: 20NIL(foo)X: 10NIL(defun bar () (foo) (let ((*x* 20)) (foo)) (foo))(bar)X: 10X: 20X: 10NIL
(defun foo () (format t "Before assignment~18tX: ~d~%" *x*) (setf *x* (+ 1 *x*)) (format t "After assignment~18tX: ~d~%" *x*))(foo)Before assignment X: 10After assignment X: 11NIL(bar)Before assignment X: 11After assignment X: 12Before assignment X: 20After assignment X: 21Before assignment X: 12After assignment X: 13NIL
(defconstant name initial-value-form [ documentation-string ])
(setf place value)
(setf x 1 y 2)
(setf x (setf y (random 10)))
(setf x (+ x 1))
(incf x) === (setf x (+ x 1))(decf x) === (setf x (- x 1))(incf x 10) === (setf x (+ x 10))
(rotatef a b)
(shiftf a b 10)