【发布时间】:2012-06-07 21:47:51
【问题描述】:
在python中可以做到这一点
EMPTY, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, BPAWN = range(8)
你会如何在 lisp 中做等价?
【问题讨论】:
标签: python common-lisp
在python中可以做到这一点
EMPTY, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, BPAWN = range(8)
你会如何在 lisp 中做等价?
【问题讨论】:
标签: python common-lisp
我曾经这样做的简单宏:
(defmacro enum-constants (&rest constants)
`(progn ,@(mapcar #'(lambda (key value) `(defconstant ,key ,value))
constants (loop for i from 0 below (length constants) collecting i))))
【讨论】:
可以使用macrolet 来计算设置一堆常量的表单:
(macrolet ((defenumvalues (&rest names)
`(progn
,@(loop for n in names and i from 0
collect `(defconstant ,n ,i))
(values))))
(defenumvalues empty pawn knight bishop rook queen king bpawn))
替代方案:使用defmacro 编写全局宏。
使用宏(本地或全局)定义一堆常量的一般优势:编译器展开表达式,然后看到一堆cl:defconstant 形式。
【讨论】:
在 Lisp 中只使用符号会更惯用。通常作为自我评估的关键字符号:
(defparameter *chess-pieces*
'(:EMPTY :PAWN :KNIGHT :BISHOP :ROOK :QUEEN :KING :BPAWN))
定义数值是有原因的——有时。尤其是当您需要与外国功能交谈时。在 Lisp 中,你会默认使用符号。
Common Lisp 没有真正的枚举类型。在动态类型语言中使用符号比使用数字变量有一些优势。例如在调试过程中,变量内容更具描述性:
比较:
> (setf c4 queen)
> c4
6
对比
> (setf c4 :queen)
> c4
:queen
在后一个示例中,符号值是自描述的。
【讨论】:
这是一种方法:
(let ((c 0))
(dolist (piece '(EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN))
(eval `(defconstant ,piece ,c))
(incf c)))
【讨论】:
假设您已经在某处 ((defun range (n) (loop :for i :from 0 :below n :collect i))) 定义了便捷函数 range,您可以像这样设置一些本地值:
(destructuring-bind (EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN)
(range 8)
#| do stuff |#)
然而,像这样的枚举很少在 Lisp 代码中使用,因为关键字(或其他符号)提供了类似的功能。
【讨论】:
写一个宏来做这件事怎么样?一个例子:
(defmacro defenum (&rest args)
(let ((counter 0))
`(progn
,@(mapcar (lambda (arg)
(cond ((symbolp arg)
(prog1
`(defparameter ,arg ,counter)
(incf counter)))
((listp arg)
(prog1
`(defparameter ,(first arg) ,(second arg))
(setf counter (1+ (second arg)))))
(t (error "broken defenum"))))
args))))
使用示例:
(defenum x (y 2) z)
(defenum EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN)
(在这个例子上可能很容易改进 :-) - 我更喜欢 defparameter 到 defconstant 所以你可能想要改变)
【讨论】:
使用默认常量:
(defconstant name initial-value-form [ documentation-string ])
例如:
(defconstant myvar 5)
【讨论】: