From: Don Geddis
Subject: Enumerations
Date: 
Message-ID: <87k5oryp3q.fsf@geddis.org>
So, way back when I was first learning how to program, I think I used Pascal
(UCSD's p-system, IIRC).  It had this nice concept of an "enumeration".
I'm not going to remember the syntax, but it worked something like this:
        enumeration Fruit: (Apple, Banana, Carrot);
        array Weight [ Fruit ];
        Weight[Apple] := 3;
        Weight[Banana] := 5;
        Weight[Carrot] := 2;

Basically, the labels in the enumeration were syntactic sugar for integers.
So the resulting code was basically the same as:
        array Weight [ 3 ];
        Weight[1] := 3;
        Weight[2] := 5;
        Weight[3] := 2;

But it was easier to read in the source code, because the mapping from
integers to real-world objects was immediately documented.

Common Lisp doesn't seem to have enumerations like this built in (unless I
missed something).  You guys ever program in this style?  What technique do
you use to get the same effect as I recall from Pascal?  I suppose that
symbol macros would work, but that seems a little like overkill (because they
aren't context-sensitive to array accesses, for example).

        -- Don
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
My friends tell me that I have a tendency to point out problems without
offering solutions, but they never tell me what I should do about it.
	-- Daniel Gilbert, "Stumbling on Happiness"

From: Barry Margolin
Subject: Re: Enumerations
Date: 
Message-ID: <barmar-C150E9.21121709112007@comcast.dca.giganews.com>
In article <··············@geddis.org>, Don Geddis <···@geddis.org> 
wrote:

> So, way back when I was first learning how to program, I think I used Pascal
> (UCSD's p-system, IIRC).  It had this nice concept of an "enumeration".
> I'm not going to remember the syntax, but it worked something like this:
>         enumeration Fruit: (Apple, Banana, Carrot);
>         array Weight [ Fruit ];
>         Weight[Apple] := 3;
>         Weight[Banana] := 5;
>         Weight[Carrot] := 2;
> 
> Basically, the labels in the enumeration were syntactic sugar for integers.
> So the resulting code was basically the same as:
>         array Weight [ 3 ];
>         Weight[1] := 3;
>         Weight[2] := 5;
>         Weight[3] := 2;
> 
> But it was easier to read in the source code, because the mapping from
> integers to real-world objects was immediately documented.
> 
> Common Lisp doesn't seem to have enumerations like this built in (unless I
> missed something).  You guys ever program in this style?  What technique do
> you use to get the same effect as I recall from Pascal?  I suppose that
> symbol macros would work, but that seems a little like overkill (because they
> aren't context-sensitive to array accesses, for example).

We usually use symbols (often in the keyword package) rather than 
integers.  If you want to associate values with them for things like 
Weight, you can use an association list or hash table, e.g.

(defparameter *weights*
  '((:apple . 3)
    (:banana . 5)
    (:carrot . 2)))

Alternatively, you can use a more object-oriented approach with 
structures or classes:

(defstruct fruit ()
  weight
  ...)

(defvar *apple* (make-fruit :weight 3 ...))
(defvar *banana* (make-fruit :weight 5 ...))
(defvar *carrot* (make-fruit :weight 2 ...))

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Don Geddis
Subject: Re: Enumerations
Date: 
Message-ID: <871wayvhx1.fsf@geddis.org>
Barry Margolin <······@alum.mit.edu> wrote on Fri, 09 Nov 2007:
> We usually use symbols (often in the keyword package) rather than 
> integers.  If you want to associate values with them for things like 
> Weight, you can use an association list or hash table, e.g.
> (defparameter *weights*
>   '((:apple . 3)
>     (:banana . 5)
>     (:carrot . 2)))

Right, but then you have to add syntax every place that you want to get
the number instead of the symbol.

> Alternatively, you can use a more object-oriented approach with 
> structures or classes:
> (defstruct fruit ()
>   weight
>   ...)
> (defvar *apple* (make-fruit :weight 3 ...))
> (defvar *banana* (make-fruit :weight 5 ...))
> (defvar *carrot* (make-fruit :weight 2 ...))

OK, but you got rid of my array.

See, I had a situation where I already had a multidimensional array
        (setq events (make-array '(3 13 32) :initial-element nil))      
Say that each array element was a list of (text) "events" for an annual
calendar at a school.  The first index was the school level (elementary,
middle, high school), the second was the month, and the third was the date.
So
        (aref events 2 4 17)
was a list of strings, referring to high-school events on April 17.

I've got code that works on this data structure just fine.  But it seems
awkward to me to have this undocumented (in the code, anyway -- maybe I could
document in the comments) relationship that each index has a meaning, and
that in the first index, 0=elementary, 1=middle, 2=high.  Etc.

It seems that the kind of code the Pascal language allowed for let me write
something like
        (aref events :high-school :april 17)
to get the same effect as the previous AREF.

So you're suggesting that I shouldn't use a multidimensional array?
That when I currently do
        (loop
           for level from 0 to 2
           do
           (loop
              for month from 1 to 12
              do
              (loop
                 for date from 1 to (days-in month)
                 do ... )))
instead I should have some classes and objects, so we have
        (defvar *elementary* ...)
        ...
        (loop
           for level in (list *elementary* *middle* *highschool*)
           ... )
And for naming the months, instead of numbering them?  You'd have some kind of
objects inside of objects thing?

I'm surprised you don't consider this (pseudocode) elegant:
        (loop
           for level from elementary to highschool
           do
           (loop
              for month from january to december
              do
              (loop
                 for date from 1 to (days-in month)
                 do ... (aref events level month date) ... )))
Or, maybe, that in principle it is elegant, but Lisp doesn't offer that
feature, so you're pointing me to the closest structures that are available.
Or did you mean to suggest that the Lisp/object solution is actually better?

I had a sudden idea: maybe I should just use variables that evaluate to
integers:
        (in-package "ENUM")
        (defparameter elementary 0)
        (defparameter middle 1)
        (defparameter high-school 2)
        (defparameter january 1)
        ...
        (in-package "COMMON-LISP-USER")
        (loop
           for level from enum:elementary to enum:high-school
           ... )

Or does everyone think that's really un-lispy and silly?

        -- Don
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
Grabel's Law:  2 is not equal to 3---not even for very large values of 2.
From: R. Matthew Emerson
Subject: Re: Enumerations
Date: 
Message-ID: <m2ode2sie2.fsf@braegen.myhome.westell.com>
Don Geddis <···@geddis.org> writes:

> I had a sudden idea: maybe I should just use variables that evaluate to
> integers:
>         (in-package "ENUM")
>         (defparameter elementary 0)
>         (defparameter middle 1)
>         (defparameter high-school 2)
>         (defparameter january 1)
>         ...
>         (in-package "COMMON-LISP-USER")
>         (loop
>            for level from enum:elementary to enum:high-school
>            ... )
>
> Or does everyone think that's really un-lispy and silly?

OpenMCL has a DEFENUM macro that's used in a few places in the system.

http://trac.clozure.com/openmcl/browser/trunk/ccl/lib/macros.lisp#L3191

It's used in circumstances like this:

(ccl::defenum (:prefix "MXCSR-" :suffix "-BIT")
  ie                                    ;invalid exception
  de                                    ;denormal exception
  ze                                    ;divide-by-zero exception
  oe                                    ;overflow exception
  ue                                    ;underflow exception
  pe                                    ;precision exception
  daz                                   ;denorms-are-zeros (not-IEEE)
  im                                    ;invalid masked
  dm                                    ;denormals masked
  zm                                    ;divide-by-zero masked
  om                                    ;overflow masked
  um                                    ;underflow masked
  pm                                    ;precision masked
  rc0                                   ;rounding control bit 0
  rc1                                   ;rounding control bit 1
  fz                                    ;flush-to-zero (not-IEEE)
)
From: Rob Warnock
Subject: Re: Enumerations
Date: 
Message-ID: <joCdna9W_8bTE6janZ2dnUVZ_tmhnZ2d@speakeasy.net>
R. Matthew Emerson <···@clozure.com> wrote:
+---------------
| Don Geddis <···@geddis.org> writes:
| > I had a sudden idea: maybe I should just use variables that
| > evaluate to integers:
| >         (in-package "ENUM")
| >         (defparameter elementary 0)
+---------------

DEFCONSTANT would probably be more appropriate here than DEFPARAMETER.

CMUCL does the same thing a lot in the UNIX package when defining bits
needed for system calls, e.g., from "cmucl-19c/src/unix.lisp":

    (defconstant o_rdonly 0 "Read-only flag.") 
    (defconstant o_wronly 1 "Write-only flag.")
    (defconstant o_rdwr   2 "Read-write flag.")

+---------------
| OpenMCL has a DEFENUM macro that's used in a few places in the system.
|   http://trac.clozure.com/openmcl/browser/trunk/ccl/lib/macros.lisp#L3191
| It's used in circumstances like this:
| (ccl::defenum (:prefix "MXCSR-" :suffix "-BIT")
|   ie                                    ;invalid exception
|   de                                    ;denormal exception
...[trimmed]...
|   rc1                                   ;rounding control bit 1
|   fz                                    ;flush-to-zero (not-IEEE)
| )
+---------------

CMUCL has a DEF-ENUM in the UNIX package that has less flexibility
in naming [the :prefix & :suffix args in OpenMCL's DEFENUM are a nice
touch here] but a *lot* more flexibility in auto-assigning values.
The macro is:

    (defmacro def-enum (inc cur &rest names)
      (flet ((defform (name)
		 (prog1 (when name `(defconstant ,name ,cur))
		   (setf cur (funcall inc cur 1)))))
	`(progn ,@(mapcar #'defform names))))

Notice that "INC CUR" values of "ASH 1" are useful for bitmasks,
while "+ 0" is useful for sequential integers from 0:

    ;; Input modes. Linux: /usr/include/asm/termbits.h
    (def-enum ash 1 tty-ignbrk tty-brkint tty-ignpar tty-parmrk tty-inpck
	      tty-istrip tty-inlcr tty-igncr tty-icrnl #-bsd tty-iuclc
	      tty-ixon #-bsd tty-ixany tty-ixoff #+bsd tty-ixany
	      #+hpux tty-ienqak #+bsd nil tty-imaxbel)

    ;; output modes
    #-bsd (def-enum ash 1 tty-opost tty-olcuc tty-onlcr tty-ocrnl tty-onocr
			tty-onlret tty-ofill tty-ofdel)
    #+bsd (def-enum ash 1 tty-opost tty-onlcr)
    ...
    ;; special control characters
    #+(or hpux svr4 linux) (def-enum + 0 vintr vquit verase vkill veof
				     #-linux veol #-linux veol2)
    #+bsd (def-enum + 0 veof veol veol2 verase nil vkill nil nil vintr vquit)
    ...

The "(WHEN NAME ...)" in the definition lets you skip values, e.g.;

    > (unix::def-enum + 1 one two nil four nil nil nil eight)

    EIGHT
    > (list eight four two one)

    (8 4 2 1)
    > 

The generality of the INC argument is somewhat marred by the fact
that the function has to have a macro-expansion-time value, so to
supply your own function you need to EVAL-WHEN it [in-line LAMBDAs
don't work here, since INC is passed *unevaluated* to FUNCALL]:

    > (eval-when (:compile-toplevel :load-toplevel :execute)
	(defun x3 (x ign)
	  (declare (ignore ign))
	  (* x 3)))

    X3
    > (unix::def-enum X3 1
	one three nine twenty-seven eighty-one two-hundred-forty-three
	seven-hundred-twenty-nine two-thousand-one-hundred-eighty-seven)

    TWO-THOUSAND-ONE-HUNDRED-EIGHTY-SEVEN
    > (list one three nine two-thousand-one-hundred-eighty-seven)

    (1 3 9 2187)
    > 


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Barry Margolin
Subject: Re: Enumerations
Date: 
Message-ID: <barmar-21A98C.12445410112007@comcast.dca.giganews.com>
In article <··············@geddis.org>, Don Geddis <···@geddis.org> 
wrote:

> Barry Margolin <······@alum.mit.edu> wrote on Fri, 09 Nov 2007:
> > We usually use symbols (often in the keyword package) rather than 
> > integers.  If you want to associate values with them for things like 
> > Weight, you can use an association list or hash table, e.g.
> > (defparameter *weights*
> >   '((:apple . 3)
> >     (:banana . 5)
> >     (:carrot . 2)))
> 
> Right, but then you have to add syntax every place that you want to get
> the number instead of the symbol.

Why do you need the number?  Those ARE the weights, there is no number.

Weight[fruit] becomes (cdr (assoc fruit *weights*))

> 
> > Alternatively, you can use a more object-oriented approach with 
> > structures or classes:
> > (defstruct fruit ()
> >   weight
> >   ...)
> > (defvar *apple* (make-fruit :weight 3 ...))
> > (defvar *banana* (make-fruit :weight 5 ...))
> > (defvar *carrot* (make-fruit :weight 2 ...))
> 
> OK, but you got rid of my array.

(setq *fruits* (vector *apple* *banana* *carrot*))

Now there's an array.

> 
> See, I had a situation where I already had a multidimensional array
>         (setq events (make-array '(3 13 32) :initial-element nil))      
> Say that each array element was a list of (text) "events" for an annual
> calendar at a school.  The first index was the school level (elementary,
> middle, high school), the second was the month, and the third was the date.
> So
>         (aref events 2 4 17)
> was a list of strings, referring to high-school events on April 17.
> 
> I've got code that works on this data structure just fine.  But it seems
> awkward to me to have this undocumented (in the code, anyway -- maybe I could
> document in the comments) relationship that each index has a meaning, and
> that in the first index, 0=elementary, 1=middle, 2=high.  Etc.

Why do you need the type of school to be an array dimension?  What's 
wrong with:

(defvar *events*
  `((elementary . ,(make-array '(13 32)))
    (middle . ,(make-array '(13 32)))
    (high . ,(make-array '(13 32)))))

Then you do:

(aref (cdr (assoc 'high *events*)) 4 17)

Arrays should be used when the keys are naturally numeric.  It seems 
like you're trying to treat the type of school numerically simply 
because you're used to doing that in other languages, because they don't 
provide good ways to work with symbols.  They forced you to turn 
everything into a number, even if it had no numeric character.

> 
> It seems that the kind of code the Pascal language allowed for let me write
> something like
>         (aref events :high-school :april 17)
> to get the same effect as the previous AREF.

If you don't want to write out the AREF CDR ASSOC every time, hide it in 
a function:

(defun get-event (school month day)
  (aref (cdr (assoc school *events*)) month day))

then you can write:

(get-event 'high 4 17)

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Don Geddis
Subject: Re: Enumerations
Date: 
Message-ID: <87sl3dsyjc.fsf@geddis.org>
Barry Margolin <······@alum.mit.edu> wrote on Sat, 10 Nov 2007:
> Arrays should be used when the keys are naturally numeric.

OK, so what about the months example?  Surely 1-12 is "naturally numeric",
yet the labels "january"-"december" are helpfully evocative to humans.

> If you don't want to write out the AREF CDR ASSOC every time, hide it in 
> a function:
> (defun get-event (school month day)
>   (aref (cdr (assoc school *events*)) month day))

Sure, I guess I can hide all my mappings this way.
        (defun get-event (month day)
          (setq month (position month '(january february ... december)))
          (aref *events* month day) )
And a slightly different form would even let me SETF (or PUSH) it as well.

I still think my suggestion, of associating labels with integers, wasn't
totally replaced by the concept of symbols in Lisp.  But I grant that I can
define an interface to my desired data structure which basically has the same
effect.

        -- Don
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
Benny Hill:  The master of the single entendre.
From: Dan Bensen
Subject: Re: Enumerations
Date: 
Message-ID: <fh543f$oaa$1@wildfire.prairienet.org>
Don Geddis wrote:
 > So, way back when I was first learning how to program, I think I used Pascal
 > (UCSD's p-system, IIRC).  It had this nice concept of an "enumeration".
 > I'm not going to remember the syntax, but it worked something like this:
 >         enumeration Fruit: (Apple, Banana, Carrot);
 >         array Weight [ Fruit ];
 >         Weight[Apple] := 3;
 >         Weight[Banana] := 5;
 >         Weight[Carrot] := 2;

C++ has this too.

enum fruit { APPLE, BANANA, CARROT, NUM_FRUITS };
int Weights[NUM_FRUITS];
...

 > Common Lisp doesn't seem to have enumerations like this built in (unless I
 > missed something).  You guys ever program in this style?  What technique do
 > you use to get the same effect as I recall from Pascal?

 > Barry Margolin <······@alum.mit.edu> wrote on Fri, 09 Nov 2007:
 >> Alternatively, you can use a more object-oriented approach with
 >> structures or classes:

This is what Martin Fowler recommended in his book Refactoring.
But add a name (and carrots aren't a fruit :)

(defstruct fruit () name weight really-a-fruit
   ...)
(defvar *apple*  (make-fruit :name "apple"  :weight 3 :really-a-fruit  t  ...))
(defvar *banana* (make-fruit :name "banana" :weight 5 :really-a-fruit  t  ...))
(defvar *carrot* (make-fruit :name "carrot" :weight 2 :really-a-fruit nil ...))

 > OK, but you got rid of my array.

 > (setq *fruits* (vector *apple* *banana* *carrot*))
 > Now there's an array.

-- 
Dan
www.prairienet.org/~dsb/
From: Pascal Costanza
Subject: Re: Enumerations
Date: 
Message-ID: <5pkcelFr23t0U1@mid.individual.net>
Don Geddis wrote:
> So, way back when I was first learning how to program, I think I used Pascal
> (UCSD's p-system, IIRC).  It had this nice concept of an "enumeration".
> I'm not going to remember the syntax, but it worked something like this:
>         enumeration Fruit: (Apple, Banana, Carrot);
>         array Weight [ Fruit ];
>         Weight[Apple] := 3;
>         Weight[Banana] := 5;
>         Weight[Carrot] := 2;
> 
> Basically, the labels in the enumeration were syntactic sugar for integers.
> So the resulting code was basically the same as:
>         array Weight [ 3 ];
>         Weight[1] := 3;
>         Weight[2] := 5;
>         Weight[3] := 2;
> 
> But it was easier to read in the source code, because the mapping from
> integers to real-world objects was immediately documented.
> 
> Common Lisp doesn't seem to have enumerations like this built in (unless I
> missed something).  You guys ever program in this style?  What technique do
> you use to get the same effect as I recall from Pascal?  I suppose that
> symbol macros would work, but that seems a little like overkill (because they
> aren't context-sensitive to array accesses, for example).

Niklaus Wirth dropped enumerations in Oberon, because they are not 
extensible: You cannot inherit an enumeration type in one part of your 
code and extend with new elements in a straightforward way, because you 
don't know whether other parts may or may not want to extend it as well. 
So the question is: How do you coordinate how the numbers are assigned 
in a distributed fashion? This will probably lead to ugly compromises.

Instead, we can simply use symbols. You can even restrict the type of a 
variable:

(deftype fruit () (member 'apple 'banana 'carrot))

(defvar *f* 'apple)
(declaim (fruit *f*))

For mapping elements of an enumeration to other values, you can just use 
association lists, property lists, hash tables, or your own dictionary 
data structures.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: George Neuner
Subject: Re: Enumerations
Date: 
Message-ID: <visbj31cc38qhfg3ef53rvs0sja682did0@4ax.com>
On Sat, 10 Nov 2007 01:31:16 +0100, Pascal Costanza <··@p-cos.net>
wrote:

>Don Geddis wrote:
>
>> Common Lisp doesn't seem to have enumerations like this built in (unless I
>> missed something).  You guys ever program in this style?  What technique do
>> you use to get the same effect as I recall from Pascal?  I suppose that
>> symbol macros would work, but that seems a little like overkill (because they
>> aren't context-sensitive to array accesses, for example).
>
>Niklaus Wirth dropped enumerations in Oberon, because they are not 
>extensible: You cannot inherit an enumeration type in one part of your 
>code and extend with new elements in a straightforward way, because you 
>don't know whether other parts may or may not want to extend it as well. 
>So the question is: How do you coordinate how the numbers are assigned 
>in a distributed fashion? This will probably lead to ugly compromises.

In Ada you can safely extend enumerations by creating a subtype which
will be compatible with the original enumeration but incompatible with
a different extension subtype.  It works well for enumerations, but
Ada's subtypes have other problems.  I think Wirth dropped
enumerations because he didn't want to deal with the problems of
general subtyping.


>Instead, we can simply use symbols. You can even restrict the type of a 
>variable:
>
>(deftype fruit () (member 'apple 'banana 'carrot))
>
>(defvar *f* 'apple)
>(declaim (fruit *f*))
>
>For mapping elements of an enumeration to other values, you can just use 
>association lists, property lists, hash tables, or your own dictionary 
>data structures.

And hide it all behind a symbol macro.


>Pascal

George
--
for email reply remove "/" from address
From: Charles Hoffman
Subject: Re: Enumerations
Date: 
Message-ID: <MEmZi.194510$Fc.9604@attbi_s21>
Pascal Costanza wrote:
> 
> (deftype fruit () (member 'apple 'banana 'carrot))
> 
> (defvar *f* 'apple)
> (declaim (fruit *f*))
> 
> For mapping elements of an enumeration to other values, you can just use 
> association lists, property lists, hash tables, or your own dictionary 
> data structures.

This seems like the closest thing to what you're looking for, at least 
in terms of how an enumeration is normally used.  The main difference 
being the implementation detail that there is no need for an underlying, 
hidden number corresponding to each symbol.  You could then write 
accessors to an association-list or hash table that would act similarly 
to the way you describe enumeration elements being used as, by checking 
that what's it's looking up by, is part of the fruit type.
From: Rainer Joswig
Subject: Re: Enumerations
Date: 
Message-ID: <joswig-376630.07371510112007@news-europe.giganews.com>
In article <··············@geddis.org>, Don Geddis <···@geddis.org> 
wrote:

> So, way back when I was first learning how to program, I think I used Pascal
> (UCSD's p-system, IIRC).  It had this nice concept of an "enumeration".
> I'm not going to remember the syntax, but it worked something like this:
>         enumeration Fruit: (Apple, Banana, Carrot);
>         array Weight [ Fruit ];
>         Weight[Apple] := 3;
>         Weight[Banana] := 5;
>         Weight[Carrot] := 2;
> 
> Basically, the labels in the enumeration were syntactic sugar for integers.
> So the resulting code was basically the same as:
>         array Weight [ 3 ];
>         Weight[1] := 3;
>         Weight[2] := 5;
>         Weight[3] := 2;
> 
> But it was easier to read in the source code, because the mapping from
> integers to real-world objects was immediately documented.
> 
> Common Lisp doesn't seem to have enumerations like this built in (unless I
> missed something).  You guys ever program in this style?

It is used in foreign function interfaces, since some external software
uses that. Sometimes the enumerations are the bits in some word, so you
have a set of bits.

Search in combination with LISP for DEFENUMERATION and DEFINE ENUMERATION.
The first brings you to DEFENUMERATION.LISP and the latter
should bring up some FFI usage.


>  What technique do
> you use to get the same effect as I recall from Pascal?  I suppose that
> symbol macros would work, but that seems a little like overkill (because they
> aren't context-sensitive to array accesses, for example).
> 
>         -- Don
> _______________________________________________________________________________
> Don Geddis                  http://don.geddis.org/               ···@geddis.org
> My friends tell me that I have a tendency to point out problems without
> offering solutions, but they never tell me what I should do about it.
> 	-- Daniel Gilbert, "Stumbling on Happiness"
From: John Thingstad
Subject: Re: Enumerations
Date: 
Message-ID: <op.t1lbp9cfut4oq5@pandora.alfanett.no>
P� Sat, 10 Nov 2007 00:29:45 +0100, skrev Don Geddis <···@geddis.org>:

> So, way back when I was first learning how to program, I think I used  
> Pascal
> (UCSD's p-system, IIRC).  It had this nice concept of an "enumeration".
> I'm not going to remember the syntax, but it worked something like this:
>         enumeration Fruit: (Apple, Banana, Carrot);
>         array Weight [ Fruit ];
>         Weight[Apple] := 3;
>         Weight[Banana] := 5;
>         Weight[Carrot] := 2;
>
> Basically, the labels in the enumeration were syntactic sugar for  
> integers.
> So the resulting code was basically the same as:
>         array Weight [ 3 ];
>         Weight[1] := 3;
>         Weight[2] := 5;
>         Weight[3] := 2;
>

Have you considered a plist instead of a array?

(defparameter weight (list :apple 3 :banana 5 :carrot 2))

(getf weigth :apple) -> 3

I find it visually less messy that a alist.


-- 
--------------
John Thingstad
From: Don Geddis
Subject: Re: Enumerations
Date: 
Message-ID: <87d4uhqt4c.fsf@geddis.org>
"John Thingstad" <·······@online.no> wrote on Sat, 10 Nov 2007:
> Have you considered a plist instead of a array?
> (defparameter weight (list :apple 3 :banana 5 :carrot 2))
> (getf weigth :apple) -> 3

You know, I hadn't.  That's not a bad idea.
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
Statisticians are people who like figures, but don't have the personality
skills to become accountants.  -- Peter Donnelly, TED (Jun 25, 2007)