Skip to content Skip to sidebar Skip to footer

How To Define Constant Like This In Lisp?

In python it's possible to do this EMPTY, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, BPAWN = range(8) How would you do equivalent in lisp?

Solution 1:

It would be more idiomatic in Lisp to just use symbols. Typically as self-evaluating keyword symbols:

(defparameter *chess-pieces*
  '(:EMPTY :PAWN :KNIGHT :BISHOP :ROOK :QUEEN :KING :BPAWN))

There are reasons to define numeric values - sometimes. Especially when you need to talk to foreign functions. In Lisp you would by default use symbols.

Common Lisp does not have a real enumeration type. Using symbols in a dynamically typed language has some advantages over using numeric variables. For example during debugging the variable contents are more descriptive:

Compare:

> (setf c4 queen)> c4
6

vs.

> (setf c4 :queen)> c4
:queen

In the latter example the symbol value is self-descriptive.

Solution 2:

Assuming that you have defined the convenience function range somewhere ((defun range (n) (loop :for i :from 0 :below n :collect i))), you could set up some local values like this:

(destructuring-bind (EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN)
    (range 8)
  #| do stuff |#)

However, enumerations like this are seldomly used in Lisp code, since keywords (or other symbols) provide similar functionality.

Solution 3:

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:

(defenumx (y 2) z)

(defenumEMPTY 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)

Solution 4:

Use defconstant:

 (defconstant name initial-value-form[ documentation-string ])

For example:

(defconstant myvar 5)

Solution 5:

Here's one way to do it:

(let ((c 0))
  (dolist (piece '(EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN))
    (eval `(defconstant ,piece ,c)) 
    (incf c)))

Post a Comment for "How To Define Constant Like This In Lisp?"