From: Markanoid
Subject: very newbie
Date: 
Message-ID: <t6snm0tts7rloo7ftabbdst663c17frnda@4ax.com>
I must do a circular list. (it is a normal list?)

i create the list
(setq lista '(1 2 3 4 5))

then define a function to add something 
(defun aggiungi (x L)
    
   ( setq L (cons x L)))

but when i call
(aggiungi 10  lista)

the result is
(10 1 2 3 4 5)

it' s ok but the nexxt time i will aspect
(10 10 1 2 3 4 5)

BUT the result is always 
(10 1 2 3 4 5)
for every time i call.
I do not understand why..  ( setq L (cons x L))) line doesn' t save my
new variable... ?

tnk fr help, bye

From: Fred Gilham
Subject: Re: very newbie
Date: 
Message-ID: <u7u0sz53ah.fsf@snapdragon.csl.sri.com>
> but when i call
> (aggiungi 10  lista)
> 
> the result is
> (10 1 2 3 4 5)

Note the following:

common-lisp-user [1]: (setq lista '(1 2 3 4 5))
Warning:  Declaring LISTA special.

(1 2 3 4 5)
common-lisp-user [2]: (defun aggiungi (x L)
    
   ( setq L (cons x L)))

AGGIUNGI
common-lisp-user [3]: (aggiungi 10  lista)

(10 1 2 3 4 5)
common-lisp-user [4]: (aggiungi 10  lista)

(10 1 2 3 4 5)
common-lisp-user [5]: lista

(1 2 3 4 5)

Does this give you a clue?

To put it in box and arrow notation (without bothering to draw the
boxes):

 lista -> | -> | -> | -> | -> | -> nil
          1    2    3    4    5


Each

    | ->

is a "cons cell", that is, it is a cell that can hold 2 data
references.  Note also that lista is a symbol.  It can hold a data
reference (along with other things).

The aggiungi function calls cons which creates a new cons cell whose
car (first data reference) is set to the x parameter and whose cdr
(second data reference) is set to the L parameter.  But note that the
L parameter is *not* a pointer to the symbol lista.  It is the
contents of the data reference that lista contains.  So the cdr of the
new cons cell is set to point to the same thing lista was pointing to:


   new
   cons
   cell
    | -> |
   10    |
         |
lista -> | -> | -> | -> | -> | -> nil
         1    2    3    4    5


So lista points to the old list structure, while aggiuni returns a
reference to a new cons cell whose first reference points to the x
value and whose second reference points to the old list that lista
points to.

To get the effect you want, you would have to do

common-lisp-user [7]: (setf lista (aggiungi 10 lista))
; 
(10 1 2 3 4 5)
common-lisp-user [8]: lista

(10 1 2 3 4 5)
common-lisp-user [9]: (setf lista (aggiungi 10 lista))

(10 10 1 2 3 4 5)
common-lisp-user [10]: lista

(10 10 1 2 3 4 5)
common-lisp-user [11]: 

-- 
Fred Gilham                                         ······@csl.sri.com
In matters of religion I have considered that its free exercise is
placed by the Constitution independent of the powers of the General
Government. I have therefore undertaken on no occasion to prescribe
the religious exercises suited to it, but have left them, as the
Constitution found them, under the direction and discipline of the
church or state authorities acknowledged by the several religious
societies.         --- Thomas Jefferson, Second Inaugural Address
From: Philip Haddad
Subject: Re: very newbie
Date: 
Message-ID: <ba57c4f9.0410121210.1ed9ff74@posting.google.com>
Markanoid <···@ngi.it> wrote in message news:<··································@4ax.com>...
> I must do a circular list. (it is a normal list?)
> 
> i create the list
> (setq lista '(1 2 3 4 5))
> 
> then define a function to add something 
> (defun aggiungi (x L)
>     
>    ( setq L (cons x L)))
> 
> but when i call
> (aggiungi 10  lista)
> 
> the result is
> (10 1 2 3 4 5)
> 
> it' s ok but the nexxt time i will aspect
> (10 10 1 2 3 4 5)
> 
> BUT the result is always 
> (10 1 2 3 4 5)
> for every time i call.
> I do not understand why..  ( setq L (cons x L))) line doesn' t save my
> new variable... ?

That's because you're variable L only has lexial scope, enough for one
use of the variable. It is released as soon as it is used by cons.
Try:
(let ((L (cons x L)))
  ......)
instead, that should work.

> tnk fr help, bye

-- 
May the Source be with you.
Philip Haddad
From: Coby Beck
Subject: Re: very newbie
Date: 
Message-ID: <B0gbd.16$cr4.13@edtnps84>
"Philip Haddad" <·············@gmail.com> wrote in message 
·································@posting.google.com...
> Markanoid <···@ngi.it> wrote in message 
> news:<··································@4ax.com>...
>> I must do a circular list. (it is a normal list?)
>>
>> i create the list
>> (setq lista '(1 2 3 4 5))
>>
>> then define a function to add something
>> (defun aggiungi (x L)
>>
>>    ( setq L (cons x L)))
>>
>> but when i call
>> (aggiungi 10  lista)
>>
>> the result is
>> (10 1 2 3 4 5)
>>
>> it' s ok but the nexxt time i will aspect
>> (10 10 1 2 3 4 5)
>>
>> BUT the result is always
>> (10 1 2 3 4 5)
>> for every time i call.
>> I do not understand why..  ( setq L (cons x L))) line doesn' t save my
>> new variable... ?
>
> That's because you're variable L only has lexial scope,

Right,

> enough for one
> use of the variable.

Don't quite know what this means?!

> It is released as soon as it is used by cons.

No (again this is non-standard terminology).  It is no longer in scope after 
the function returns.

> Try:
> (let ((L (cons x L)))
>  ......)
> instead, that should work.

That won't work.


-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
From: Frank Buss
Subject: Re: very newbie
Date: 
Message-ID: <ckh089$et3$1@newsreader2.netcologne.de>
Markanoid <···@ngi.it> wrote:

> I must do a circular list. (it is a normal list?)

no, a circular list is a list where the last cdr points to the first
cons: 

http://groups.google.de/groups?threadm=uwGc9O%23f9GA.330%40nih2naac.prod2.compuserve.com 

> i create the list
> (setq lista '(1 2 3 4 5))

you should not use setq for declaring or changing new variables at
top-level: 

http://groups.google.de/groups?selm=_badnZ8rXbR-G0rd4p2dnA%40speakeasy.net 

> then define a function to add something 
> (defun aggiungi (x L)
>     
>    ( setq L (cons x L)))

you should read the article about variables in the nice book from Peter
Seibel and try to understand what "lexical binding" means: 

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

BTW: The "push" macro implements what you want with your
function aggiungi:

CL-USER 1 > (defparameter *lista* '(1 2 3 4 5))
*LISTA*

CL-USER 2 > (push 10 *lista*)
(10 1 2 3 4 5)

CL-USER 3 > (push 20 *lista*)
(20 10 1 2 3 4 5)

CL-USER 4 > *lista*
(20 10 1 2 3 4 5)

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Svein Ove Aas
Subject: Re: very newbie
Date: 
Message-ID: <ckh59m$5t7$2@services.kq.no>
Frank Buss wrote:

> BTW: The "push" macro implements what you want with your
> function aggiungi:
> 
> CL-USER 1 > (defparameter *lista* '(1 2 3 4 5))
> *LISTA*
> 
> CL-USER 2 > (push 10 *lista*)
> (10 1 2 3 4 5)
> 
> CL-USER 3 > (push 20 *lista*)
> (20 10 1 2 3 4 5)
> 
> CL-USER 4 > *lista*
> (20 10 1 2 3 4 5)
> 

Note that this only works because push is a macro, and can't be implemented
as a function. The push macro expands to (setf *lista* (cons 10 lista)). 
From: Pascal Bourguignon
Subject: Re: very newbie
Date: 
Message-ID: <87r7o3ri5t.fsf@thalassa.informatimago.com>
Markanoid <···@ngi.it> writes:

> I must do a circular list. (it is a normal list?)
> 
> i create the list
> (setq lista '(1 2 3 4 5))
> 
> then define a function to add something 
> (defun aggiungi (x L)
>     
>    ( setq L (cons x L)))
> 
> but when i call
> (aggiungi 10  lista)
> 
> the result is
> (10 1 2 3 4 5)

That's because Lisp does not call by reference, it calls by value, like C!

So when you pass lista to aggiungi, L gets the value of lista, ie  (1
2 3 4 5), and knows nothing about lista.

It happens that setq returns the last value assigned so you get the
right result, but you did not change lista!

Forget about setting in a _function_. Use a functional style:

    (defun aggiungi (x l)
        (cons x l))

    (defparameter lista '(1 2 3 4 5))
    (setf lista (aggiungi 10 lista))
    (setf lista (aggiungi 11 lista))


> it' s ok but the nexxt time i will aspect
> (10 10 1 2 3 4 5)
> 
> BUT the result is always 
> (10 1 2 3 4 5)
> for every time i call.
> I do not understand why..  ( setq L (cons x L))) line doesn' t save my
> new variable... ?
> 
> tnk fr help, bye

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

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Frank Buss
Subject: Re: very newbie
Date: 
Message-ID: <ckh5ne$ngu$1@newsreader2.netcologne.de>
Pascal Bourguignon <····@mouse-potato.com> wrote:

> That's because Lisp does not call by reference, it calls by value,
> like C! 
> 
> So when you pass lista to aggiungi, L gets the value of lista, ie  (1
> 2 3 4 5), and knows nothing about lista.

this is a bit misleading. You are right, you can't change the variable, 
but the list is bound like a pointer, so it is like a C-pointer (a 
reference would be a C-pointer-pointer or a C++ reference). With this in 
mind you can hack it like this (to the OP: don't do it like this, the 
following is really ugly code and not something a Lisp programmer expects 
from a function!)

(defun aggiungi (x l)
  (let ((next-object (car l))
        (next-cons (cdr l)))
    (rplaca l x)
    (rplacd l (cons next-object next-cons))))

CL-USER > (defparameter *l* '(1 2 3))
*L*

CL-USER > (aggiungi 10 *l*)
(10 1 2 3)

CL-USER > (aggiungi 20 *l*)
(20 10 1 2 3)

CL-USER > *l*
(20 10 1 2 3)

> Forget about setting in a _function_. Use a functional style:
> 
>     (defun aggiungi (x l)
>         (cons x l))
> 
>     (defparameter lista '(1 2 3 4 5))
>     (setf lista (aggiungi 10 lista))
>     (setf lista (aggiungi 11 lista))

yes, this would be better, or using a macro.

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Peter Seibel
Subject: Re: very newbie
Date: 
Message-ID: <m3ekk3n5bu.fsf@javamonkey.com>
Frank Buss <··@frank-buss.de> writes:

> Pascal Bourguignon <····@mouse-potato.com> wrote:
>
>> That's because Lisp does not call by reference, it calls by value,
>> like C! 
>> 
>> So when you pass lista to aggiungi, L gets the value of lista, ie  (1
>> 2 3 4 5), and knows nothing about lista.
>
> this is a bit misleading. You are right, you can't change the variable, 
> but the list is bound like a pointer, so it is like a C-pointer (a 
> reference would be a C-pointer-pointer or a C++ reference). With this in 
> mind you can hack it like this (to the OP: don't do it like this, the 
> following is really ugly code and not something a Lisp programmer expects 
> from a function!)
>
> (defun aggiungi (x l)
>   (let ((next-object (car l))
>         (next-cons (cdr l)))
>     (rplaca l x)
>     (rplacd l (cons next-object next-cons))))
>
> CL-USER > (defparameter *l* '(1 2 3))
> *L*
>
> CL-USER > (aggiungi 10 *l*)
> (10 1 2 3)
>
> CL-USER > (aggiungi 20 *l*)
> (20 10 1 2 3)
>
> CL-USER > *l*
> (20 10 1 2 3)

A more important that this is a bad idea is it doesn't work with all
lists:

  CL-USER> (aggiungi 10 nil)

  Attempt to store in the car field of NIL which is not a cons.
     [Condition of type SIMPLE-ERROR]

  Restarts:
    0: [ABORT] Abort handling SLIME request.
    1: [ABORT] Abort entirely from this process.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Svein Ove Aas
Subject: Re: very newbie
Date: 
Message-ID: <ckh54l$5t7$1@services.kq.no>
Pascal Bourguignon wrote:

> Markanoid <···@ngi.it> writes:
> 
>> I must do a circular list. (it is a normal list?)
>> 
>> i create the list
>> (setq lista '(1 2 3 4 5))
>> 
>> then define a function to add something
>> (defun aggiungi (x L)
>>     
>>    ( setq L (cons x L)))
>> 
>> but when i call
>> (aggiungi 10  lista)
>> 
>> the result is
>> (10 1 2 3 4 5)
> 
> That's because Lisp does not call by reference, it calls by value, like C!
> 
This is at least misleading; while Lisp does indeed call by value, many of
those values happen to be references. As follows...

> So when you pass lista to aggiungi, L gets the value of lista, ie  (1
> 2 3 4 5), and knows nothing about lista.
> 
L gets the value of lista, but fundamentally the value of lista isn't (1 2 3
4 5); it's (1 x), with x being a pointer to (2 3 4 5). The scheme is
approximately the same as in Java, in fact.

Another way to write lista would be as (1 . (2 . (3 . (4 . (5 . nil))))).
Only the outermost layer is passed by value, and that value includes a
reference to the inner layers.

> It happens that setq returns the last value assigned so you get the
> right result, but you did not change lista!
> 
This is true. lista isn't changed, only L is. The only thing you can do to L
that would work is to append something to it, and that's messy - it would
only work if lista is a list of two or more elements, which is rarely what
you want.

> Forget about setting in a _function_. Use a functional style:
> 
>     (defun aggiungi (x l)
>         (cons x l))
> 
>     (defparameter lista '(1 2 3 4 5))
>     (setf lista (aggiungi 10 lista))
>     (setf lista (aggiungi 11 lista))
> 
This is good advice, and probably the best way to do it.

> 
>> it' s ok but the nexxt time i will aspect
>> (10 10 1 2 3 4 5)
>> 
>> BUT the result is always
>> (10 1 2 3 4 5)
>> for every time i call.
>> I do not understand why..  ( setq L (cons x L))) line doesn' t save my
>> new variable... ?
>> 
>> tnk fr help, bye
> 

-- 
 
From: Markanoid
Subject: Re: very newbie
Date: 
Message-ID: <1amom0hc9b2of2633bo55ttpj6a8hse7kl@4ax.com>
>I must do a circular list. (it is a normal list?)
>
>i create the list
>(setq lista '(1 2 3 4 5))
>
>then define a function to add something 
>(defun aggiungi (x L)
Thank you everyone for responses,
lisp is difficult but with a community like this become simpler.

Tomorrow i will try to correct my program, now i' m quite happy
because i cannod do it right because it was impossible. 
I wanted create first of all a circular list;
than a function  that append an atom to the list; all this avoid usng
macros , using pure lisp (at least using set) but now i think it is
impossible because there is no way to savesomting fo a futher
reelaboration.
Bye
From: Kenny Tilton
Subject: Re: very newbie
Date: 
Message-ID: <uGZad.163092$4h7.29641902@twister.nyc.rr.com>
Markanoid wrote:
>>I must do a circular list. (it is a normal list?)
>>
>>i create the list
>>(setq lista '(1 2 3 4 5))
>>
>>then define a function to add something 
>>(defun aggiungi (x L)
> 
> Thank you everyone for responses,
> lisp is difficult but with a community like this become simpler.
> 
> Tomorrow i will try to correct my program, now i' m quite happy
> because i cannod do it right because it was impossible. 
> I wanted create first of all a circular list;
> than a function  that append an atom to the list; all this avoid usng
> macros , using pure lisp (at least using set) but now i think it is
> impossible because there is no way to savesomting fo a futher
> reelaboration.

Yes there is. You just have to do exactly that: "save something"

    (setq *lista* (aggiungi 10 *lista*))

As someone noted, your particular example is something done by the macro 
PUSH:

    (push 10 *lista*)

...but that works only because it expands into the same thing as above:

    (macroexpand-1 '(push atom list))
    => (SETQ LIST (CONS ATOM LIST))

You would have the same situation in "C", by the way, if you just passed 
   to aggiungi a variable containing the address of the first link in a 
linked list. You would have to pass the address of the /variable/, which 
is what Lisp does not do.

This is a frequent newby (and oldby) mistake with Lisp: even when using 
destructive functions, one must often capture the result returned by the 
destructive function. Knowing when requires /really/ understanding CONS, 
CAR, and CDR, and (in this case) that the (setq L...) in your code was 
not acting on *lista*.

kenny


-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Pascal Bourguignon
Subject: Re: very newbie
Date: 
Message-ID: <878yabqypj.fsf@thalassa.informatimago.com>
Markanoid <···@ngi.it> writes:

> >I must do a circular list. (it is a normal list?)
> >
> >i create the list
> >(setq lista '(1 2 3 4 5))
> >
> >then define a function to add something
> >(defun aggiungi (x L)
> Thank you everyone for responses,
> lisp is difficult but with a community like this become simpler.
>
> Tomorrow i will try to correct my program, now i' m quite happy
> because i cannod do it right because it was impossible.
> I wanted create first of all a circular list;

Note that transforming a proper list into a circular list can be done
and without needing the variable that hold the head of the list!
But is that what you want?


You're starting with a proper list:
      +-----------------------------------------------------------+
      |  lst = (A B C D E)                                        |
      |   |                                                       |
      |   v                                                       |
      | +---+---+   +---+---+   +---+---+   +---+---+   +---+---+ |
      | | * | * |-->| * | * |-->| * | * |-->| * | * |-->| * |NIL| |
      | +---+---+   +---+---+   +---+---+   +---+---+   +---+---+ |
      |   |           |           |           |           |       |
      |   v           v           v           v           v       |
      | +---+       +---+       +---+       +---+       +---+     |
      | | A |       | B |       | C |       | D |       | E |     |
      | +---+       +---+       +---+       +---+       +---+     |
      +-----------------------------------------------------------+


And you want to end with a circular list:
      +-----------------------------------------------------------+
      |  lst = (A B C D E)                                        |
      |   |+--------------------------------------------------+   |
      |   ||                                                  |   |
      |   vv                                                  |   |
lista | +---+---+   +---+---+   +---+---+   +---+---+   +---+---+ |
  +---|>| * | * |-->| * | * |-->| * | * |-->| * | * |-->| * | * | |
      | +---+---+   +---+---+   +---+---+   +---+---+   +---+---+ |
      |   |           |           |           |           |       |
      |   v           v           v           v           v       |
      | +---+       +---+       +---+       +---+       +---+     |
      | | A |       | B |       | C |       | D |       | E |     |
      | +---+       +---+       +---+       +---+       +---+     |
      +-----------------------------------------------------------+

If you have other variables holding the first cons cell, you can see
that they will see the change as well.  You may note too that only the
last cons cell is changed, namely it's cdr.  And that it must now
point to the first cons cell, the one that is referenced ot by lst.

So, we have: last, cdr, setf, lst.  You should be able make it circular:

    (defun loop-the-loop (lst)
        (____ (____ (____ ____)) ____)) ;; fill the spaces.


Note that since loop-the-loop will modify the list, you cannot pass it
a list that appears in the source. No '(a b c d e)! You have to
construct the list (with cons or list), or copy a literal list.

    (setf *print-circle* t)

    (defparameter lista (copy-seq '(1 2 3 4 5)))
    (loop-the-loop lista)
    lista

    (defparameter listb (list 'a 'b 'c 'd 'e)))
    (loop-the-loop listb)
    listb



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

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Svein Ove Aas
Subject: Re: very newbie
Date: 
Message-ID: <ckls5g$jmo$1@services.kq.no>
K. Ari Krupnikov wrote:

> Pascal Bourguignon <····@mouse-potato.com> writes:
> 
>> Note that since loop-the-loop will modify the list, you cannot pass it
>> a list that appears in the source. No '(a b c d e)! You have to
>> construct the list (with cons or list), or copy a literal list.
> 
> Stupid question - why?

Depending on the implementation, that list may be in read-only space
(hopefully), or ordinary space. (More likely)

Obviously, modifying it won't work in the first case. In the second it will,
but you get undefined behaviour... what's most likely to happen is that the
list will get modified, and it'll *stay* modified, meaning that the next
invocation of the same code won't read the same constant as it did the
first time.

And no, you may *not* use this to make static variables. That's what
closures are for. 
From: K. Ari Krupnikov
Subject: Re: very newbie
Date: 
Message-ID: <86oej4rd8j.fsf@fdra.lib.aero>
Svein Ove Aas <·········@aas.no> writes:

> K. Ari Krupnikov wrote:
> 
> > Pascal Bourguignon <····@mouse-potato.com> writes:
> > 
> >> Note that since loop-the-loop will modify the list, you cannot pass it
> >> a list that appears in the source. No '(a b c d e)! You have to
> >> construct the list (with cons or list), or copy a literal list.
> > 
> > Stupid question - why?
> 
> Depending on the implementation, that list may be in read-only space
> (hopefully), or ordinary space. (More likely)
> 
> Obviously, modifying it won't work in the first case. In the second it will,
> but you get undefined behaviour... what's most likely to happen is that the
> list will get modified, and it'll *stay* modified, meaning that the next
> invocation of the same code won't read the same constant as it did the
> first time.

You mean next time I say '(1 2 3 4 5) I'll get the modified, circular
copy?

Ari.

-- 
Elections only count as free and trials as fair if you can lose money
betting on the outcome.
From: Pascal Bourguignon
Subject: Re: very newbie
Date: 
Message-ID: <87sm8gmx1z.fsf@thalassa.informatimago.com>
···@lib.aero (K. Ari Krupnikov) writes:

> Svein Ove Aas <·········@aas.no> writes:
> 
> > K. Ari Krupnikov wrote:
> > 
> > > Pascal Bourguignon <····@mouse-potato.com> writes:
> > > 
> > >> Note that since loop-the-loop will modify the list, you cannot pass it
> > >> a list that appears in the source. No '(a b c d e)! You have to
> > >> construct the list (with cons or list), or copy a literal list.
> > > 
> > > Stupid question - why?
> > 
> > Depending on the implementation, that list may be in read-only space
> > (hopefully), or ordinary space. (More likely)
> > 
> > Obviously, modifying it won't work in the first case. In the second it will,
> > but you get undefined behaviour... what's most likely to happen is that the
> > list will get modified, and it'll *stay* modified, meaning that the next
> > invocation of the same code won't read the same constant as it did the
> > first time.
> 
> You mean next time I say '(1 2 3 4 5) I'll get the modified, circular
> copy?

Exactly.

CL-USER> (setf *print-circle* t)
T
CL-USER> (defun give-a-list () '(1 2 3 4 5))
GIVE-A-LIST
CL-USER> (defparameter x (give-a-list))
X
CL-USER> x
(1 2 3 4 5)
CL-USER> (setf (cdr (last x)) x)
#1=(1 2 3 4 5 . #1#)
CL-USER> x
#1=(1 2 3 4 5 . #1#)
CL-USER> (give-a-list)
#1=(1 2 3 4 5 . #1#)
CL-USER> (function-lambda-expression 'give-a-list)
(LAMBDA NIL (DECLARE (SYSTEM::IN-DEFUN GIVE-A-LIST))
 (BLOCK GIVE-A-LIST '#1=(1 2 3 4 5 . #1#)))
#(NIL NIL NIL NIL ((DECLARATION VALUES OPTIMIZE DECLARATION)))
GIVE-A-LIST
CL-USER> 

'(1 2 3 4 5) was in the source, you modified the source.  Literal data
will stay even in compiled code, so you could be modifying even a
compiled fonction!

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

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Markanoid
Subject: Re: very newbie
Date: 
Message-ID: <t2h5n0p8ll9am9cskglvsb434s2ibkr5e4@4ax.com>
Il Tue, 12 Oct 2004 22:28:24 GMT, Markanoid <···@ngi.it> ha scritto:

>>I must do a circular list. (it is a normal list?)
>>
>>i create the list
>>(setq lista '(1 2 3 4 5))
>>
>>then define a function to add something 
>>(defun aggiungi (x L)
>Thank you everyone for responses,
>lisp is difficult but with a community like this become simpler.
>
>Tomorrow i will try to correct my program, now i' m quite happy
>because i cannod do it right because it was impossible. 
>I wanted create first of all a circular list;
>than a function  that append an atom to the list; all this avoid usng
>macros , using pure lisp (at least using set) but now i think it is
>impossible because there is no way to savesomting fo a futher
>reelaboration.
>Bye


I finished my newbies program, tell me if it' s fine ;)
(implementation of a FIFO list withoutusing macro (close to pure
lisp))

;FUNCIONS
(defun lung (L)
   (if (null L) 0
   (+ 1(lung(cdr L)))))

(defun aggiungi (x L)
   (if (= (lung L) 5) L
   (cons x L)))

(defun rimuovi (L)
   (if (null (cdr L))(cdr L)
   (cons(car L)(rimuovi (cdr L)))))

; WRITE AT RUNTIME...
(setq lista (list ))
(setq lista (list 34 5 67 89 078 89))

(setq lista (aggiungi 1 lista))
(setq lista (aggiungi 2 lista))
(setq lista (aggiungi 3 lista))
(setq lista (aggiungi 4 lista))
(setq lista (aggiungi 5 lista))
(setq lista (aggiungi 9 lista))

(setq lista (rimuovi lista))

(lung lista)



tk, bye
From: Pascal Bourguignon
Subject: Re: very newbie
Date: 
Message-ID: <87wtxp3z1c.fsf@thalassa.informatimago.com>
-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Pascal Bourguignon
Subject: Re: very newbie
Date: 
Message-ID: <87sm8d3xt9.fsf@thalassa.informatimago.com>
Markanoid <···@ngi.it> writes:
> I finished my newbies program, tell me if it' s fine ;)
> (implementation of a FIFO list withoutusing macro (close to pure
> lisp))
> 
> ;FUNCIONS
> (defun lung (L)
>    (if (null L) 0
>    (+ 1(lung(cdr L)))))
>
> (defun aggiungi (x L)
>    (if (= (lung L) 5) L
>    (cons x L)))
> 
> (defun rimuovi (L)
>    (if (null (cdr L))(cdr L)
>    (cons(car L)(rimuovi (cdr L)))))
> 
> ; WRITE AT RUNTIME...
> (setq lista (list ))
> (setq lista (list 34 5 67 89 078 89))
> 
> (setq lista (aggiungi 1 lista))
> (setq lista (aggiungi 2 lista))
> (setq lista (aggiungi 3 lista))
> (setq lista (aggiungi 4 lista))
> (setq lista (aggiungi 5 lista))
> (setq lista (aggiungi 9 lista))
> 
> (setq lista (rimuovi lista))
> 
> (lung lista)

1- define the API (the abstract type).
2- implement it.

For example:

1- for an informal specification of the abstract data type FIFO:

    (make-fifo max-count) --> fifo

    (fifo-max-count fifo) --> integer
    (fifo-max-count (make-fifo x)) == x

    (fifo-count fifo) --> integer
    (fifo-count (make-fifo x)) == 0

    (fifo-enqueue fifo element) --> fifo
    if (fifo-count fifo) < (fifo-max-count fifo) 
    then (fifo-count (fifo-enqueue fifo x)) == 1 + (fifo-count fifo)
    else (fifo-count (fifo-enqueue fifo x)) == (fifo-count fifo)

    if (fifo-count fifo) == 0 
    then (fifo-dequeue fifo) --> nil
    else (fifo-dequeue fifo) --> element

    
2- implementation:

    (defun make-fifo (max-count) 
        (assert (and (integerp max-count) (< 0 max-count)))
        (list :fifo max-count 0 nil nil))

    (defun fifo-max-count (fifo) 
        (assert (and (listp fifo) (eq :fifo (first fifo))))
        (second fifo))

    (defun fifo-count (fifo)
        (assert (and (listp fifo) (eq :fifo (first fifo))))
        (third fifo))

    (defun fifo-enqueue (fifo element)
        (assert (and (listp fifo) (eq :fifo (first fifo))))
        (cond ((= (second fifo) (third fifo)))
              ((null (fourth fifo)) 
                 (setf (fourth fifo) (list element)
                       (fifth fifo) (fourth fifo)
                       (third fifo) 1))
              (t (setf (cdr (fifth fifo) (list element))
                       (fifth fifo) (cdr (fifth fifo)))
                 (incf (third fifo))))
         fifo)

    (defun fifo-dequeue (fifo)
        (assert (and (listp fifo) (eq :fifo (first fifo))))
        (when (< 0 (third fifo))
           (prog1 (pop (fourth fifo))
              (when (null (fourth fifo))
                 (setf (fifth fifo) nil))
                 (decf (third fifo)))))

As you can see, even though I did not use car/cdr/caddr, etc, it's
quite hard to read. Common-Lisp provides you with several tools to
implement such data structures: defstruct or defclass for example.

    (defstruct fifo
        (max-count 5   :type (integer 1))
        (count     0   :type (integer 0))
        (head      nil :type list)
        (tail      nil :type list))

This automatically generates the following useful functions:

    make-fifo
    fifo-max-count
    fifo-count
    fifo-head
    fifo-tail

Remains to implement:

    (defun fifo-enqueue (fifo element)
        (assert (typep fifo 'fifo))
        (cond ((= (fifo-count fifo) (fifo-max-count fifo)))
              ((null (fifo-head fifo))
                 (setf (fifo-head fifo) (list element)
                       (fifo-tail fifo) (fifo-head fifo)
                       (fifo-count fifo) 1))
              (t (setf (cdr (fifo-tail fifo)) (list element)
                       (fifo-tail fifo) (cdr (fifo-tail fifo)))
                 (incf (fifo-count fifo))))
        fifo)


    (defun fifo-dequeue (fifo)
        (assert (typep fifo 'fifo))
        (when (< 0 (fifo-count fifo))
            (prog1 (pop (fifo-head fifo))
                (decf (fifo-count fifo))
                (when (null (fifo-head fifo))
                    (setf (fifo-tail fifo) nil)))))

If you need to have the fifo type be implemented with cons cells for
any reason (instead of a _structure_, you can merely change the
defstruct declaration:


    (defstruct (fifo (:type list))
        (max-count 5   :type (integer 1))
        (count     0   :type (integer 0))
        (head      nil :type list)
        (tail      nil :type list))
 
       
Then the implementation will be exactly the same as above with cons
cells, only fifo-count is more readable than third or caddr.

    (defparameter q (make-fifo :max-count 5))
    (dolist (e '(il etait une souris verte qui courrait dans l\'herbe))
        (fifo-enqueue q e))
    (dotimes (i (fifo-count q))
        (print (fifo-dequeue q)))

prints:

    IL
    ETAIT
    UNE
    SOURIS
    VERTE

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

Voting Democrat or Republican is like choosing a cabin in the Titanic.