From: yang
Subject: lisp newbie question: how can I associate  properties to list cells?
Date: 
Message-ID: <465f0892-5440-4c54-9826-7a2156d29c48@f20g2000yqg.googlegroups.com>
for a symbol, 'a, I can do
 (setf (get 'a 'state) 'finish)

so that 'a has a property state with value finish,

I want to know how to do similar things for lisp. set a property and
value for each cell in the list
eg:  given a list
(setq lst '(1 2 3 1))

(setf  (get (car lst ) 'state) 'finish)
will report an error.

properties are bound to symbol names other than list cells. how can I
specify properties for cells ?
thanks

From: Tamas K Papp
Subject: Re: lisp newbie question: how can I associate  properties to list cells?
Date: 
Message-ID: <6p8c1pF6h63vU1@mid.individual.net>
On Thu, 27 Nov 2008 11:44:46 -0800, yang wrote:

> for a symbol, 'a, I can do
>  (setf (get 'a 'state) 'finish)
> 
> so that 'a has a property state with value finish,
> 
> I want to know how to do similar things for lisp. set a property and
> value for each cell in the list
> eg:  given a list
> (setq lst '(1 2 3 1))
> 
> (setf  (get (car lst ) 'state) 'finish) will report an error.
> 
> properties are bound to symbol names other than list cells. how can I
> specify properties for cells ?

As you said, symbols have properties.  Values don't (in contrast to, say, 
attributes in R).  You will have to find a different mechanism for 
storing that information.  Depending on your needs, the following come to 
mind:

- an object with 'value' and 'properties' slots, the latter an assoc list 
or a hash table (faster)
- structure using the same logic
- cons cell (ugly)

HTH,

Tamas
From: John Thingstad
Subject: Re: lisp newbie question: how can I associate  properties to list cells?
Date: 
Message-ID: <op.ulatu3z1ut4oq5@pandora.alfanett.no>
P� Thu, 27 Nov 2008 20:44:46 +0100, skrev yang <·········@gmail.com>:

> for a symbol, 'a, I can do
>  (setf (get 'a 'state) 'finish)
>
> so that 'a has a property state with value finish,
>
> I want to know how to do similar things for lisp. set a property and
> value for each cell in the list
> eg:  given a list
> (setq lst '(1 2 3 1))
>
> (setf  (get (car lst ) 'state) 'finish)
> will report an error.
>
> properties are bound to symbol names other than list cells. how can I
> specify properties for cells ?
> thanks


(defparameter *enum* '(:one 1 two 2 :three 3))

(getf *enum* :one)
> 1


--------------
John Thingstad
From: William James
Subject: Re: lisp newbie question: how can I associate properties to list 	cells?
Date: 
Message-ID: <2ca79684-ef2f-404c-a185-941f75bc05a5@w34g2000yqm.googlegroups.com>
On Nov 27, 4:24 pm, "John Thingstad" <·······@online.no> wrote:
> På Thu, 27 Nov 2008 20:44:46 +0100, skrev yang <·········@gmail.com>:
>
>
>
>
>
> > for a symbol, 'a, I can do
> >  (setf (get 'a 'state) 'finish)
>
> > so that 'a has a property state with value finish,
>
> > I want to know how to do similar things for lisp. set a property and
> > value for each cell in the list
> > eg:  given a list
> > (setq lst '(1 2 3 1))
>
> > (setf  (get (car lst ) 'state) 'finish)
> > will report an error.
>
> > properties are bound to symbol names other than list cells. how can I
> > specify properties for cells ?
> > thanks
>
> (defparameter *enum* '(:one 1 two 2 :three 3))
>
> (getf *enum* :one)
>
> > 1

Ruby:

enum = { :one, 1, :two, 2, :three, 3 }
    ==>{:one=>1, :two=>2, :three=>3}
enum[:one]
    ==>1
From: William James
Subject: Re: lisp newbie question: how can I associate properties to listcells?
Date: 
Message-ID: <ggpp0o$2sg$1@aioe.org>
John Thingstad wrote:

> P� Thu, 27 Nov 2008 20:44:46 +0100, skrev yang <·········@gmail.com>:
> 
> > for a symbol, 'a, I can do
> > (setf (get 'a 'state) 'finish)
> > 
> > so that 'a has a property state with value finish,
> > 
> > I want to know how to do similar things for lisp. set a property and
> > value for each cell in the list
> > eg:  given a list
> > (setq lst '(1 2 3 1))
> > 
> > (setf  (get (car lst ) 'state) 'finish)
> > will report an error.
> > 
> > properties are bound to symbol names other than list cells. how can
> > I specify properties for cells ?
> > thanks
> 
> 
> (defparameter enum '(:one 1 two 2 :three 3))
> 
> (getf enum :one)
> > 1

JavaScript:

js> enum = { one: 1, two: 2, three: 3 }
[object Object]
js> enum.one
1
js> enum['three']
3
From: =?UTF-8?B?QW5kcsOpIFRoaWVtZQ==?=
Subject: Re: lisp newbie question: how can I associate properties to listcells?
Date: 
Message-ID: <ggq208$chv$1@news.motzarella.org>
William James schrieb:
> John Thingstad wrote:
> 
>> På Thu, 27 Nov 2008 20:44:46 +0100, skrev yang <·········@gmail.com>:
>>
>>> for a symbol, 'a, I can do
>>> (setf (get 'a 'state) 'finish)
>>>
>>> so that 'a has a property state with value finish,
>>>
>>> I want to know how to do similar things for lisp. set a property and
>>> value for each cell in the list
>>> eg:  given a list
>>> (setq lst '(1 2 3 1))
>>>
>>> (setf  (get (car lst ) 'state) 'finish)
>>> will report an error.
>>>
>>> properties are bound to symbol names other than list cells. how can
>>> I specify properties for cells ?
>>> thanks
>>
>> (defparameter enum '(:one 1 two 2 :three 3))
>>
>> (getf enum :one)
>>> 1

 > Ruby:
 >
 > enum = { :one, 1, :two, 2, :three, 3 }
 >     ==>{:one=>1, :two=>2, :three=>3}
 > enum[:one]
 >     ==>1
> 
> JavaScript:
> 
> js> enum = { one: 1, two: 2, three: 3 }
> [object Object]
> js> enum.one
> 1
> js> enum['three']
> 3

In Clojure:
(def enum {:one 1 :two 2 :three 3})

And then
(:one enum) ==> 1

Or also:
(get enum :two) ==> 2


André
-- 
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/
From: Pascal J. Bourguignon
Subject: Re: lisp newbie question: how can I associate  properties to list cells?
Date: 
Message-ID: <871vww4x6l.fsf@hubble.informatimago.com>
yang <·········@gmail.com> writes:

> for a symbol, 'a, I can do
>  (setf (get 'a 'state) 'finish)
>
> so that 'a has a property state with value finish,
>
> I want to know how to do similar things for lisp. set a property and
> value for each cell in the list
> eg:  given a list
> (setq lst '(1 2 3 1))
>
> (setf  (get (car lst ) 'state) 'finish)
> will report an error.
>
> properties are bound to symbol names other than list cells. how can I
> specify properties for cells ?
> thanks

You have to refine your specifications.

For example, with the list you gave, what should we get for:

    (let ((list '(1 2 3 1)))
      (setf (get-property (first list) 'state) 'finish)
      (get-property (fourth list) 'state)) 

?

Once you've run the above expression, should the following expression
return anything useful?

    (get-property '1 'state) 


Or do you want to be able to do:

    (let ((list '(1 2 3 1)))
      (setf (get-property (first list) 'state) 'finish)
      (setf (first list) 42)
      (values (get-property (first list) 'state)
              list))
    --> FINISH ;
        (42 2 3 1)

?



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

THIS IS A 100% MATTER PRODUCT: In the unlikely event that this
merchandise should contact antimatter in any form, a catastrophic
explosion will result.
From: Robert Maas, http://tinyurl.com/uh3t
Subject: Re: lisp newbie question: how can I associate  properties to list cells?
Date: 
Message-ID: <REM-2008nov27-004@Yahoo.Com>
> From: yang <·········@gmail.com>
> for a symbol, 'a, I can do
>  (setf (get 'a 'state) 'finish)
> so that 'a has a property state with value finish,

Yes, because each symbol is an object (not in the OOP sense, more
like in the STRUCT sense) which has several slots: the print-name,
the value cell, the function cell, the package cell, and the
property-list. You can't change the print-name (or shouldn't
anyway), but any of the other slots can be changed at any time
(although you probably don't want to change the package cell unless
 you *really* know what you are doing).

> I want to know how to do similar things for lisp. set a property
> and value for each cell in the list
> eg:  given a list
> (setq lst '(1 2 3 1))

When you say (each) "cell" (in the list), do you mean:
- The CONS cell that is used to build the linked list?
- The value of the element at that position in the list?
- The *position* of that CONS cell (and corresponding element) in the list?

It makes a difference!!

If the property is with the CONS cell, or with the position within
the list, then replacing any of the elements with new values
doesn't change the property. But if the property is associated with
the value itself then changing the value will mean you're using a
different property cell, and if the same value occurs twice then
the *same* property will be associated with *it* regardless of how
you access it.

If the property is associated with the CONS cell itself, then if
you rearrange the CONS cells the properties will move with them.
But if the property is associated with the (numeric) position
within the list, then when you rearrage the CONS cells within the
list, even dicard them and replace them with new CONS cells from
elsewhere, the third of the list will retain the same property the
third had when the third was something different.

Do you understand the distinction between the three kinds of
associations? If so, you need to decide which of the three
semantics you had in mind. Then here is how I would suggest
implementing it:

For matching value to property, use a hash table keyed on the value
(element). You need to decide whether it's to be matched per EQL
(the default) or some other equivalence relation (EQ and EQUAL are
standard). Given the element (value), GETHASH will give the
property associated with it.

For matching on the CONS cell, use an EQ hash table keyed on the
CONS cell itself, not the value under it. Given the (pointer to)
the CONS cell, GETHASH will give the property associated with it.

For matching on the numeric position within the list, use parallel
list that has the properties. Given the index, NTH will give the
corresponding property. Given the CONS cell, a variation of
POSITION will give the index, or NIL if the cell isn't in the list
any longer. Given the element, POSITION will give the first
position with that value, and successive POSITION with :START will
give successive positions *also* having that same value, so you can
retrieve multiple properties for all places some element appears.

Here's my attempt at writing that variant of POSITION which finds
the index of a CONS cell in a list, in case you need it:

(defun cell-position (list targetCell)
  (loop for ix from 0
        for thisCell on list
    when (eq thisCell targetCell) return ix))

(setq foo (list 3 1 4 1 5 9 2 6 5 3 5)) ;Head of list, intentionally whole list
(setq baz (nthcdr 7 foo)) ;A cell within that list, intentionally just that cell
(cell-position foo baz) ;Position of that cell within that list
=> 7
(rplacd (nthcdr 2 foo) (nthcdr 5 foo))
(cell-position foo baz)
=> 5

(Nitpick on intentional data types: Although in Lisp, internally
 the value of foo is just the CONS cell at the head of the linked
 list, the intention of foo is the whole list, not just that first
 cell. But the intention of baz is to point at just one cell within
 foo, not to imply the entire tail from that point to the end of
 the list.)

> how can I specify properties for cells ?

When you say "cells", do you actually mean the CONS cells
themselves as distinct intentional objects? Or one of the other two
meanings I listed above?

Note that if you never mutate the sequence of CONS cells within
that list, such as by calling SORT on it, then it doesn't matter
whether you hash on CONS cell identity or have parallel list using
numeric postition within list, because the relation between the two
is unchanged. And if you have no duplicate values within the list,
and you never change any value in the list, then hashing the value
instead of the CONS cell is likewise equivalent. If all three are
permanently equivalent, then the parallel list is more efficient.
But if you want to establish properties for more than one such
list, and have a single mechanism to do them all instead of a
different mechanism for each such list, and allow the same value in
different lists or places within a single list to have different
properties, then EQ hashing of the CONS cell is probably best.

Note that in *any* of the three cases, if you want more than one
property for each item (CONS cell, or position, or element value),
then use a detached property list or an association list in place
of a single value, depending on whether you want replacement or
masking semantics respectively for the various named properties.

I'll guess that you want replacement semantics, same as with
property lists associated with symbols, so use a detached property
list as the hash value. Look at the manual or hyperspec for
functions getf and remf, analagous to get and remprop when using
detached property lists located in places in lieu of ordinary
property lists attached to symbols. For example (using baz from
above):
  (defvar $CONS-EQ-HASH-TABLE$ (make-hash-table :test #'EQ))
  (setf (getf (gethash baz $CONS-EQ-HASH-TABLE$) :PROP1) "Heather") ;Set prop
  (getf (gethash baz $CONS-EQ-HASH-TABLE$) :PROP1) ;Retrieve prop
  (remf (gethash baz $CONS-EQ-HASH-TABLE$) :PROP1) ;Erase prop

Disclaimer for SETQ haters and DEFVAR nitpickers: I used SETQ of
foo and baz, because presumably they would be local variables
within some function. During interactive debugging you can ignore
the warning you get about them being special. But I used DEFVAR
with $CONS-EQ-HASH-TABLE$ because presumably that would be a
global that really should be proclaimed a special variable.