From: jonathon
Subject: Experimenting with Lisp, question about looping with structures
Date: 
Message-ID: <1114027871.291793.311330@l41g2000cwc.googlegroups.com>
Hi all,

I have a simple concept: a transaction structure with several fields.
I read data from the prompt, populate the fields, then show the result.
 This works fine so far.

The transaction manager is a class with just one slot ATM: a list of
transaction structures.

I'm having problems finding the correct combination of operations that
will return to me a list of lists of transaction slot values that I can
then print.

I'm using list, append, and loop...collecting, but I cannot seem to get
the combo correct.

Any suggestions?  It's a newbie question, but so far, I'm pretty
inspired by what I've seen.

From: Mikko Heikelä
Subject: Re: Experimenting with Lisp, question about looping with structures
Date: 
Message-ID: <Pine.OSF.4.61.0504202321560.148908@kosh.hut.fi>
On Wed, 20 Apr 2005, jonathon wrote:
>
> I have a simple concept: a transaction structure with several fields.

> The transaction manager is a class with just one slot ATM: a list of 
> transaction structures.
>
> I'm having problems finding the correct combination of operations that
> will return to me a list of lists of transaction slot values that I can
> then print.

Is this what you want?

(mapcar #'transaction-to-list (transactions transaction-manager))

Transaction-to-list is supposed to return a list of slot values in 
a single transaction, i.e. it is something like:

(defun transaction-to-list (transaction)
   (list (transaction-slot-1 transaction)
         (transaction-slot-2 transaction)
         (transaction-slot-n transaction)))

-Mikko Heikel�
From: jonathon
Subject: Re: Experimenting with Lisp, question about looping with structures
Date: 
Message-ID: <1114052598.071404.189000@g14g2000cwa.googlegroups.com>
Mikko Heikelä wrote:
> Is this what you want?
>
> (mapcar #'transaction-to-list (transactions transaction-manager))

Did you mean
(mapcar #'transaction-to-list (transactions) transaction-manager)

I'm not sure... still learning.  What is 'transaction-manager' there
for?

> Transaction-to-list is supposed to return a list of slot values in
> a single transaction, i.e. it is something like:
>
> (defun transaction-to-list (transaction)
>    (list (transaction-slot-1 transaction)
>          (transaction-slot-2 transaction)
>          (transaction-slot-n transaction)))

The only problem here is I do not know how many transactions will
exist.  1 to n is possible.

Jonathon
From: Geoffrey Summerhayes
Subject: Re: Experimenting with Lisp, question about looping with structures
Date: 
Message-ID: <%bG9e.5404$9G.554103@news20.bellglobal.com>
"jonathon" <···········@bigfoot.com> wrote in message ·····························@g14g2000cwa.googlegroups.com...
>Mikko Heikel� wrote:
>> Is this what you want?
>>
>> (mapcar #'transaction-to-list (transactions transaction-manager))
>
>Did you mean
>(mapcar #'transaction-to-list (transactions) transaction-manager)

No.

>I'm not sure... still learning.  What is 'transaction-manager' there
>for?

(defclass transaction-manager ()
  ((list :accessor transactions :initform '())))

(defparameter transaction-manager
  (make-instance 'transaction-manager))

It's the instance of the transaction manager. It's there for
the same reason that it says (transaction-slot-1 transaction) in
what follows.

>> Transaction-to-list is supposed to return a list of slot values in
>> a single transaction, i.e. it is something like:
>>
>> (defun transaction-to-list (transaction)
>>    (list (transaction-slot-1 transaction)
>>          (transaction-slot-2 transaction)
>>          (transaction-slot-n transaction)))
>
>The only problem here is I do not know how many transactions will
>exist.  1 to n is possible.

No offense, but it sounds like you're jumping in at the
deep end before you learn how to swim.
The Common Lisp Hyperspec is your friend, look up mapcar.

http://www.lispworks.com/documentation/HyperSpec/Front/index.htm

Also check out:

http://www.gigamonkeys.com/book/

and if you like it show support and get the portable,
go-everywhere, dead tree edition.

--
Geoff 
From: Mikko Heikelä
Subject: Re: Experimenting with Lisp, question about looping with structures
Date: 
Message-ID: <Pine.OSF.4.61.0504211036250.235812@kosh.hut.fi>
On Thu, 20 Apr 2005, jonathon wrote:
> Mikko Heikel� wrote:
>> Is this what you want?
>>
>> (mapcar #'transaction-to-list (transactions transaction-manager))
>
> Did you mean
> (mapcar #'transaction-to-list (transactions) transaction-manager)
>
> I'm not sure... still learning.  What is 'transaction-manager' there
> for?

Geoffrey explained this in his post.

>> Transaction-to-list is supposed to return a list of slot values in
>> a single transaction, i.e. it is something like:
>>
>> (defun transaction-to-list (transaction)
>>    (list (transaction-slot-1 transaction)
>>          (transaction-slot-2 transaction)
>>          (transaction-slot-n transaction)))
>
> The only problem here is I do not know how many transactions will
> exist.  1 to n is possible.

In the above you are dealing with a single transaction and you only 
need to know how to access the slots in it.  That is what
(transaction-slot-1 transaction) etc. do.  The above would work for a 
transaction structure defined with:

(defstruct transaction slot-1 slot-2 slot-n).

Although in reality you would have sensible slot and accessor names.

To sum up:  If I understood correctly, you asked how to turn a list of 
structures into a list of lists of their slot values.  The function 
transaction-to-list takes a single transaction and returns a list of 
its slot values.  Looping over the list of transactions and 
constructing (top level structure of) the result list are taken care 
of by mapcar.

I notice that the subject says looping with structures, whereas I have 
given looping over lists and constructing lists from structures.  Do 
you want to do something else entirely?

   Mikko Heikel�
From: jonathon
Subject: Re: Experimenting with Lisp, question about looping with structures
Date: 
Message-ID: <1114094825.178338.211580@f14g2000cwb.googlegroups.com>
> To sum up:  If I understood correctly, you asked how to turn a list
of
> structures into a list of lists of their slot values.  The function
> transaction-to-list takes a single transaction and returns a list of
> its slot values.  Looping over the list of transactions and
> constructing (top level structure of) the result list are taken care
> of by mapcar.

I took another look and I understand now.

I think the problem is in how I am saving the transactions in the
transactionmanager:

(defstruct transactionmanager
  transactions :initform nil)

(defun make-tm ()
  (make-transactionmanager))

(defun add-transaction (tm tr)
  (with-slots (transactions) tm
    (setf transactions (list transactions tr))
;    (setf transactions (append transactions tr))
    (format t "Added.~%Transactions: ~{~a~% ~}~%" transactions)))


The list 'transactions' is not coming out correctly.  I've tried
substituting the above commented-out line, but that does not create the
list correctly either.

>
> I notice that the subject says looping with structures, whereas I
have
> given looping over lists and constructing lists from structures.  Do
> you want to do something else entirely?

No, you have it right.  Thanks for your help.
From: jonathon
Subject: Re: Experimenting with Lisp, question about looping with structures
Date: 
Message-ID: <1114096602.261277.135680@o13g2000cwo.googlegroups.com>
I figured it out.

This is the correct code I needed:

(defun add-transaction (tm tr)
  (with-slots (transactions) tm
      (setf transactions (append transactions (list tr)))
      (format t "Added.~%Transactions: ~{~a~% ~}~%" transactions)))

So now this works (the original question)

(defmethod dump-transactions (tm)
  (with-slots (transactions) tm
    (dolist (tr transactions)
      (show-transaction tr))))


Thanks for your help!
From: Marco Antoniotti
Subject: Re: Experimenting with Lisp, question about looping with structures
Date: 
Message-ID: <ytU9e.4$mi7.24494@typhoon.nyu.edu>
jonathon wrote:
>>To sum up:  If I understood correctly, you asked how to turn a list
> 
> of
> 
>>structures into a list of lists of their slot values.  The function
>>transaction-to-list takes a single transaction and returns a list of
>>its slot values.  Looping over the list of transactions and
>>constructing (top level structure of) the result list are taken care
>>of by mapcar.
> 
> 
> I took another look and I understand now.
> 
> I think the problem is in how I am saving the transactions in the
> transactionmanager:
> 
> (defstruct transactionmanager
>   transactions :initform nil)

(defstruct transaction-manager
    (transactions () :type list))

to be verbose.  You are mixing DEFSTRUCT and DEFCLASS

> (defun make-tm ()
>   (make-transactionmanager))
> 
> (defun add-transaction (tm tr)
>   (with-slots (transactions) tm
>     (setf transactions (list transactions tr))
> ;    (setf transactions (append transactions tr))
>     (format t "Added.~%Transactions: ~{~a~% ~}~%" transactions)))
> 

(defmethod add-transaction ((tm transaction-manager) (tr transaction))
    (setf (transaction-manager-transactions tm)
          (nconc (transaction-manager-transactions tm) (list tr))))

(defmethod add-transaction :around ((tm transaction-manager) (tr 
transaction))
    (call-next-method)
    (format t "Added transaction ~A.~%Transactions:~{~&~A~%~}~%"
            (transaction-manager-transactions tm)))




Cheers

--
Marco
From: Mikko Heikelä
Subject: Re: Experimenting with Lisp, question about looping with structures
Date: 
Message-ID: <Pine.OSF.4.61.0504211817080.465225@kosh.hut.fi>
On Thu, 21 Apr 2005, jonathon wrote:

> I think the problem is in how I am saving the transactions in the
> transactionmanager:

> (defun add-transaction (tm tr)
>  (with-slots (transactions) tm
>    (setf transactions (list transactions tr))
> ;    (setf transactions (append transactions tr))
>    (format t "Added.~%Transactions: ~{~a~% ~}~%" transactions)))

Also the last argument to append has to be a list in order to get a 
proper list as a result.

(setf transactions (append transactions (list tr)))

should work.  If you can stand having the list in the opposite order, 
you can simply use push:

(push tr transactions)

   Mikko Heikel�