Pythonではこれを行うことができます
EMPTY, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, BPAWN = range(8)
Lispで同等のことをどのように行いますか?
Pythonではこれを行うことができます
EMPTY, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, BPAWN = range(8)
Lispで同等のことをどのように行いますか?
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
後者の例では、シンボル値は自己記述的です。
range
便利な関数をどこか ( ) で定義したと仮定すると、次の(defun range (n) (loop :for i :from 0 :below n :collect i))
ようなローカル値を設定できます。
(destructuring-bind (EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN)
(range 8)
#| do stuff |#)
しかし、このような列挙は、キーワード (または他のシンボル) が同様の機能を提供するため、Lisp コードではめったに使用されません。
What about writing a macro to do this? An example:
(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))))
Examples of usage:
(defenum x (y 2) z)
(defenum EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN)
(it's probably very easy to improve on this example :-) - I prefer defparameter
to defconstant
so that's something you may want to change)
デフコンスタントを使用:
(defconstant name initial-value-form [ documentation-string ])
例えば:
(defconstant myvar 5)
私がちょうどそれを行っていた単純なマクロ:
(defmacro enum-constants (&rest constants)
`(progn ,@(mapcar #'(lambda (key value) `(defconstant ,key ,value))
constants (loop for i from 0 below (length constants) collecting i))))
これを行う1つの方法は次のとおりです。
(let ((c 0))
(dolist (piece '(EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN))
(eval `(defconstant ,piece ,c))
(incf c)))