From: DaveNlp
Subject: nconc question
Date: 
Message-ID: <Qcycb.346084$lK4.11069383@twister1.libero.it>
Hi,
I have a question about (nconc).
That is my function.

(defun get-entries (from-nth to-nth wlist)
    (let* ((rlist nil)
           (ipos 0))
        (dolist (sym wlist rlist)
            (setq ipos (1+ ipos))
            (if (and (>= ipos from-nth) (<= ipos to-nth))
                (setf rlist (nconc rlist (list sym)))))))

In this way it works well.

>(get-entries 2 3 '("abc" "def" "ghi" "jkl" "mno" "pqr"))
>("def" "ghi")

Since (nconc) appends lists destructively I supposed that (setf) is not
more necessary.

(defun get-entries (from-nth to-nth wlist)
    (let* ((rlist nil)
           (ipos 0))
        (dolist (sym wlist rlist)
            (setq ipos (1+ ipos))
            (if (and (>= ipos from-nth) (<= ipos to-nth))
                (nconc rlist (list sym))))))

>(get-entries 1 3 '("abc" "def" "ghi" "jkl" "mno" "pqr"))
>nil

..but in this way doesn't seems to work, why?
I have changed (setf (nconc) ...) only.

Thank you in advance.
DaveNlp.

From: Kaz Kylheku
Subject: Re: nconc question
Date: 
Message-ID: <cf333042.0309251013.60a898b7@posting.google.com>
"DaveNlp" <(NOSPAM)·········@iol.it> wrote in message news:<·························@twister1.libero.it>...
> Hi,
> I have a question about (nconc).
> That is my function.
> 
> (defun get-entries (from-nth to-nth wlist)
>     (let* ((rlist nil)
>            (ipos 0))
>         (dolist (sym wlist rlist)
>             (setq ipos (1+ ipos))
>             (if (and (>= ipos from-nth) (<= ipos to-nth))
>                 (setf rlist (nconc rlist (list sym)))))))
> 
> In this way it works well.
> 
> >(get-entries 2 3 '("abc" "def" "ghi" "jkl" "mno" "pqr"))
> >("def" "ghi")
> 
> Since (nconc) appends lists destructively I supposed that (setf) is not
> more necessary.

A destructive append can still produce a list whose first cons cell is
some other object than the leftmost argument! This happens when the
leftmost list is NIL:

   (let ((orig-list ()))
     (nconc orig-list '(a b c)) ...)

Here, NCONC basically returned the '(a b c) object. But ORIG-LIST
remains bound to NIL.
 
A Lisp list isn't a container data structure, but either NIL or a
pointer to the a cons cell.

When it's a pointer to a cons, it's possible to destructively append.
When it's the NIL symbol, then there is no structure there to append
to.

> (defun get-entries (from-nth to-nth wlist)
>     (let* ((rlist nil)
>            (ipos 0))
>         (dolist (sym wlist rlist)
>             (setq ipos (1+ ipos))
>             (if (and (>= ipos from-nth) (<= ipos to-nth))
>                 (nconc rlist (list sym))))))
> 
> >(get-entries 1 3 '("abc" "def" "ghi" "jkl" "mno" "pqr"))
> >nil
> 
> ..but in this way doesn't seems to work, why?

It fails to bootstrap the RLIST variable out of the NIL state in the
very first iteration for the above reasons. Since RLIST evaluates to
NIL, NCONC just returns the value of (LIST SYM): it doesn't in fact
have to destructively manipulate anything at all.
From: Frode Vatvedt Fjeld
Subject: Re: nconc question
Date: 
Message-ID: <2hn0ctmdit.fsf@vserver.cs.uit.no>
"DaveNlp" <(NOSPAM)·········@iol.it> writes:

> (defun get-entries (from-nth to-nth wlist)
>     (let* ((rlist nil)
>            (ipos 0))
>         (dolist (sym wlist rlist)
>             (setq ipos (1+ ipos))
>             (if (and (>= ipos from-nth) (<= ipos to-nth))
>                 (nconc rlist (list sym))))))
>
>>(get-entries 1 3 '("abc" "def" "ghi" "jkl" "mno" "pqr"))
>>nil
>
> ..but in this way doesn't seems to work, why?
> I have changed (setf (nconc) ...) only.

The question is not why it doesn't work, but why you think this would
work. Nconc is a function that---disregarding its side-effecting
potential---does the same as append. Substitute nconc with append in
your code, and you will probably see what is wrong.

The key to understanding this is to understanding the difference
between functions (and how they are evaluated) and operators that work
on "places", which are Lisp's version of "named pointers", if you
like.

-- 
Frode Vatvedt Fjeld
From: Nikodemus Siivola
Subject: Re: nconc question
Date: 
Message-ID: <bkujj0$t0c$1@nyytiset.pp.htv.fi>
DaveNlp <(NOSPAM)·········@iol.it> wrote:

> Since (nconc) appends lists destructively I supposed that (setf) is
> not more necessary.

You need to understand the difference between:

 "may modify it's aguments destructively"

   and

 "is used for it's side-effects".

NCONC may modify it's agruments destructively, so you must not pass it
anything needed elsewere. It is *not* however used for it's
side-effects: you need the return-value just like with APPEND.

Whenever you are using something else then SETF for side-effects in
Lisp you are *probably* either wrong or doing IO.

Cheers,

 -- Nikodemus
From: Barry Margolin
Subject: Re: nconc question
Date: 
Message-ID: <qYCcb.47$pd.39@news.level3.com>
In article <············@nyytiset.pp.htv.fi>,
Nikodemus Siivola  <······@random-state.net> wrote:
>DaveNlp <(NOSPAM)·········@iol.it> wrote:
>
>> Since (nconc) appends lists destructively I supposed that (setf) is
>> not more necessary.
>
>You need to understand the difference between:
>
> "may modify it's aguments destructively"
>
>   and
>
> "is used for it's side-effects".
>
>NCONC may modify it's agruments destructively, so you must not pass it
>anything needed elsewere. It is *not* however used for it's
>side-effects: you need the return-value just like with APPEND.

Actually, unlike most of the other destructive list functions, NCONC's
destruction is well-defined.  It's *required* to modify the cdr of the last
cons in the list.

The reason the SETF is still needed is to handle the case where the first
argument is NIL.

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Donald Fisk
Subject: Re: nconc question
Date: 
Message-ID: <3F72C590.2E0C8CF@enterprise.net>
DaveNlp wrote:
> 
> Hi,
> I have a question about (nconc).
> That is my function.
> 
> (defun get-entries (from-nth to-nth wlist)
>     (let* ((rlist nil)
>            (ipos 0))
>         (dolist (sym wlist rlist)
>             (setq ipos (1+ ipos))
>             (if (and (>= ipos from-nth) (<= ipos to-nth))
>                 (setf rlist (nconc rlist (list sym)))))))
> 
> In this way it works well.
> 
> >(get-entries 2 3 '("abc" "def" "ghi" "jkl" "mno" "pqr"))
> >("def" "ghi")
> 
> Since (nconc) appends lists destructively I supposed that (setf) is not
> more necessary.
> 
> (defun get-entries (from-nth to-nth wlist)
>     (let* ((rlist nil)
>            (ipos 0))
>         (dolist (sym wlist rlist)
>             (setq ipos (1+ ipos))
>             (if (and (>= ipos from-nth) (<= ipos to-nth))
>                 (nconc rlist (list sym))))))
> 
> >(get-entries 1 3 '("abc" "def" "ghi" "jkl" "mno" "pqr"))
> >nil
> 
> ..but in this way doesn't seems to work, why?

Have you tried inserting print statements into your
code to find out what's going on?

> I have changed (setf (nconc) ...) only.

Try doing the same thing interactively:

* (setf rlist nil)
NIL
* (setf rlist (nconc rlist (list 'foo)))
(FOO)
* rlist
(FOO)

compared with

* (setf rlist nil)
NIL
* (nconc rlist (list 'foo))
(FOO)
* rlist
NIL

and think why NCONC doesn't change the value of RLIST
when RLIST is initially NIL.

BTW there are some things you could do to improve
your code.   SYM isn't necessarily a symbol.   Compare
the definitions of LET and LET* and you'll see that
LET* isn't necessary here.   Look up the definition
of INCF.   Use SETQ and SETF consistently.   UNLESS
there is an `else' part to an IF expression, you can
use WHEN.

Finally, consider what happens to the performance of your
algorithm when RLIST becomes very long -- it's like
painting a line in the road without ever moving the
paint pot.

> DaveNlp.

-- 
:ugah179 (home page: http://web.onetel.com/~hibou/)

"I'm outta here.  Python people are much nicer."
                -- Erik Naggum (out of context)
From: Kenny Tilton
Subject: Re: nconc question
Date: 
Message-ID: <AuCcb.13638$lZ6.4044963@twister.nyc.rr.com>
Donald Fisk wrote:

> Finally, consider what happens to the performance of your
> algorithm when RLIST becomes very long -- it's like
> painting a line in the road without ever moving the
> paint pot.

Ouch. nice image.

:)

kt
From: DaveNlp
Subject: Re: nconc question
Date: 
Message-ID: <eLFcb.347540$lK4.11101068@twister1.libero.it>
"Donald Fisk" <················@enterprise.net> ha scritto nel messaggio
>
> compared with
>
> * (setf rlist nil)
> NIL
> * (nconc rlist (list 'foo))
> (FOO)
> * rlist
> NIL
>
> and think why NCONC doesn't change the value of RLIST
> when RLIST is initially NIL.

Ok.
I tried to change my function for working without (setf).

(defun get-entries (from-nth to-nth wlist)
    (let ((rlist (list nil))
           (ipos 0))
        (dolist (sym wlist (rest rlist))
            (setq ipos (1+ ipos))
            (if (and (>= ipos from-nth) (<= ipos to-nth))
                (nconc rlist (list sym))))))

By hint of another Lisper I have decided for changing my function
definitely
with this below, even if there is more checks that I must do..

(defun get-entries2 (from-nth to-nth wlist)
    (let ((llst (length wlist)))
        (unless (and (> from-nth llst) (> to-nth llst))
          (unless (and (< from-nth 1) (< to-nth 1))
            (unless (< to-nth from-nth)
                (if (< from-nth 1) (setq from-nth 1))
                (if (> to-nth llst) (setq to-nth llst))
                (subseq wlist (1- from-nth) to-nth))))))

I did forgot to say that all list elements are only strings.

Greetings.
DaveNlp.
From: Jorge Tavares
Subject: Re: nconc question
Date: 
Message-ID: <bkuhqu$6eq$1@rena.mat.uc.pt>
Hi,

> That is my function.
> 
> (defun get-entries (from-nth to-nth wlist)
>     (let* ((rlist nil)
>            (ipos 0))
>         (dolist (sym wlist rlist)
>             (setq ipos (1+ ipos))
>             (if (and (>= ipos from-nth) (<= ipos to-nth))
>                 (setf rlist (nconc rlist (list sym)))))))

Just a suggestion: try using loop with collect.
IMHO it is more simple :-)


Best Regards,
Jorge

-- 
Jorge Tavares
http://www.dei.uc.pt/~jast

"Evolution is the best engineer."
From: Pierpaolo BERNARDI
Subject: Re: nconc question
Date: 
Message-ID: <VnIcb.122037$hE5.4175235@news1.tin.it>
"Jorge Tavares" <····@dei.uc.pt> ha scritto nel messaggio ·················@rena.mat.uc.pt...

> Just a suggestion: try using loop with collect.
> IMHO it is more simple :-)

If he was after simpleness, he could have just
used SUBSEQ.

P.
From: Jorge Tavares
Subject: Re: nconc question
Date: 
Message-ID: <bkvm51$oa4$1@rena.mat.uc.pt>
Hi,

> If he was after simpleness, he could have just
> used SUBSEQ.

True! And I must confess I didn�t remember it at the first time because
I was just thinking of solutions envolving iteration.

Jorge

-- 
Jorge Tavares
http://www.dei.uc.pt/~jast

"Evolution is the best engineer."
From: Wolfhard Buß
Subject: Re: nconc question
Date: 
Message-ID: <m3smml6uxi.fsf@buss-14250.user.cis.dfn.de>
* DaveNlp:
|
| (defun get-entries (from-nth to-nth wlist)
|     (let* ((rlist nil)
|            (ipos 0))
|         (dolist (sym wlist rlist)
|             (setq ipos (1+ ipos))
|             (if (and (>= ipos from-nth) (<= ipos to-nth))
|                 (nconc rlist (list sym))))))
| 
| >(get-entries 1 3 '("abc" "def" "ghi" "jkl" "mno" "pqr"))
| >nil
| 
| ..but in this way doesn't seems to work, why?
| I have changed (setf (nconc) ...) only.
 
Does the evaluation of (nconc nil list) cause any side effects?

Why not simply push sym to the front of rlist and finally return rlist
nreversed?

Do you need to walk over the whole list?

Check your arguments...


-- 
"Hurry if you still want to see something. Everything is vanishing."
                                       --  Paul C�zanne (1839-1906)
From: DaveNlp
Subject: Re: nconc question
Date: 
Message-ID: <XXGcb.347764$lK4.11109950@twister1.libero.it>
"Wolfhard Bu�" <·····@gmx.net> ha scritto nel messaggio
···················@buss-14250.user.cis.dfn.de...
> * DaveNlp:
> |
> | (defun get-entries (from-nth to-nth wlist)
> |     (let* ((rlist nil)
> |            (ipos 0))
> |         (dolist (sym wlist rlist)
> |             (setq ipos (1+ ipos))
> |             (if (and (>= ipos from-nth) (<= ipos to-nth))
> |                 (nconc rlist (list sym))))))
> |
> | >(get-entries 1 3 '("abc" "def" "ghi" "jkl" "mno" "pqr"))
> | >nil
> |
> | ..but in this way doesn't seems to work, why?
> | I have changed (setf (nconc) ...) only.
>
> Does the evaluation of (nconc nil list) cause any side effects?
>
> Why not simply push sym to the front of rlist and finally return rlist
> nreversed?

Good hint, thanks you. :)

> Do you need to walk over the whole list?

Not necessarily.
(get-entries) is the conversion of a function that I wrote in C
for use with one-level sequential lists.
Probably in Lisp is more easier to do without
to walk over the whole list, using multi-level lists.

Greetings
DaveNlp.