Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
There has got to be a better way...
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 26 - 50 of 73 - Collapse all  -  Translate all to Translated (View all originals) < Older  Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Erik Naggum  
View profile  
 More options Apr 26 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Erik Naggum <e...@naggum.no>
Date: 1999/04/26
Subject: Re: There has got to be a better way...
* paul_ru...@scientia.com
| At the risk of rehashing old ground: what is "unnecessary" waste is
| partly a matter of opinion.  The space and/or time efficiency of lots of
| code can be improved on.  The question is how much effort one wants to
| invest in doing so.

  I can understand why you cons up new articles with the same old defense
  for the same old unskilled Lisp style rather than reuse existing defenses
  by reference...

#:Erik


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tim Bradshaw  
View profile  
 More options Apr 26 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Tim Bradshaw <t...@tfeb.org>
Date: 1999/04/26
Subject: Re: There has got to be a better way...
* Lyman S Taylor wrote:

> Tim Bradshaw wrote:
>   But nested lists are trees. :-)   At least you can look at them that
>   way in this context, removing the nesting.

Yes, they are, but you get a choice over which side (car or cdr) you
recurse on and which you iterate over.  Quite apart from being just
wrong (sigh), my answer recurses on the cdr and iterates (assuming the
system does TRO, which before anyone picks me up, I know is not a safe
assumption) on the car.  So if I want something which deals with
things I'm thinking of as `lists' -- ie things which are probably
deep in the cdr direction but not in the car direction then that's a
bad choice, because I'd like my program not to blow up however long
the list is.

--tim

(I think what I'd write is actually something like

    (defun collapse-list (list)
      (let ((a '())
            (at nil))
        (labels ((collect (x)
                   (if at
                       (setf (cdr at) (list x)
                             at (cdr at))
                       (setf a (list x)
                             at a)))
                 (clist (l)
                   (dolist (e l a)
                     (if (atom e)
                         (collect e)
                         (clist e)))))
          (clist list))))

Except I'd write it as:

    (defun collapse-list (list)
      (collecting
       (iterate clist (l)
         (dolist (e l)
           (if (atom e)
               (collect e)
               (clist e))))))

And the point of showing that is that it's using DOLIST to go along
the lists and DOLIST shouldn't eat stack).


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kenneth P. Turvey  
View profile  
 More options Apr 26 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: ktur...@pug1.sprocketshop.com (Kenneth P. Turvey)
Date: 1999/04/26
Subject: Re: There has got to be a better way...
On 26 Apr 1999 19:11:13 +0200, Stig Hemmer <s...@pvv.ntnu.no> wrote:
[Snip]

>Given that (EQ NIL ()), it is impossible to do this right without
>defining what "right" means in this context.

>So, to the original poster: How should NIL be treated? As an atom and
>included, or as an empty list and flattened away?

[Snip]

For my purposes, NIL should be treated as an atom.  I can see how this
would depend on the application though.

I must admit, I had no idea what a can of worms I was opening with this
question.  It has been quite educational.

--
Kenneth P. Turvey <ktur...@SprocketShop.com>

  In America, any boy may become president and I suppose that's just one
  of the risks he takes.
        -- Adlai Stevenson


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tim Bradshaw  
View profile  
 More options Apr 26 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Tim Bradshaw <t...@tfeb.org>
Date: 1999/04/26
Subject: Re: There has got to be a better way...

* I wrote:
>     (defun collapse-list (list)
>       (collecting
>        (iterate clist (l)
>     (dolist (e l)
>       (if (atom e)
>           (collect e)
>           (clist e))))))

Sigh.

     (defun collapse-list (list)
       (collecting
        (iterate clist ((l list))
         (dolist (e l)
           (if (atom e)
               (collect e)
               (clist e))))))

--tim


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
paul_rudin  
View profile  
 More options Apr 27 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: paul_ru...@scientia.com
Date: 1999/04/27
Subject: Re: There has got to be a better way...
In article <7g2ccl$su...@nnrp1.dejanews.com>,
  Vassil Nikolov <vniko...@poboxes.com> wrote:

> Not that hard, perhaps.  What if, by the law of perverse solutions,
> the backquote construct is implemented so that for `(,x) it does
> a REPLACA on the cons produced by the reader when it processed the
> opening parenthesis.  I'd like to be corrected that this is illegal.

No I think you're right; a quick look at Steele suggests that anything EQUAL
to (list x) would be OK here.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Marco Antoniotti  
View profile  
 More options Apr 27 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Marco Antoniotti <marc...@copernico.parades.rm.cnr.it>
Date: 1999/04/27
Subject: Re: There has got to be a better way...

ENDP ?

Cheers

--
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
ey15  
View profile  
 More options Apr 27 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: e...@liv.ac.uk (ey15)
Date: 1999/04/27
Subject: Re: There has got to be a better way...
In article <slrn7i2s0b.oj4.ktur...@pug1.sprocketshop.com>, ktur...@pug1.sprocketshop.com
says...

>particularly concerned with performance.  I would like to see a simple
>and elegant solution.

I can't say if this one is simple or eligant, but it seams to work...

(defun collapse-list (l)
  (loop with result = (list nil)
        with result-tail = result
        for item in l
        if (atom item)
        do (rplacd result-tail (list item))
           (setq result-tail (cdr result-tail))
        else
        do (rplacd result-tail (collapse-list item))
           (setq result-tail (last result-tail))
        end
        finally return (cdr result)))

(setq l '((nil a nil (((((((((((nil))))))))))) s d nil) q w r (d f (4 r t 6 (h j s l) r k l
(d g)) sv) s f j c ()))

CL-USER 76 > (collapse-list l)
(NIL A NIL NIL S D NIL Q W R D F 4 R T 6 H J S L R K L D G SV S F J C NIL)

BTW, I came up with this solution after looking at the results of
(pprint (macroexpand '(loop for item in l collect item)))

Marcus.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Howard R. Stearns  
View profile  
 More options Apr 27 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: "Howard R. Stearns" <how...@elwood.com>
Date: 1999/04/27
Subject: Re: There has got to be a better way...

Kent M Pitman wrote:
> ...  You want #'(lambda (x) (funcall fn x))
> in situations like this.  [Or if you have the lisp machine's circular-list
> function, (mapcar #'funcall (circular-list fn) lists).  Admittedly
> obscure, but some use it idiomatically--almost to the point that I think
> the compiler should have had an optimizer for it that turned it back
> into something that didn't waste the single cons needed to make the circular
> list.]

What is circular-list?

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kent M Pitman  
View profile  
 More options Apr 27 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Kent M Pitman <pit...@world.std.com>
Date: 1999/04/27
Subject: Re: There has got to be a better way...

paul_ru...@scientia.com writes:
> In article <7g2ccl$su...@nnrp1.dejanews.com>,
>   Vassil Nikolov <vniko...@poboxes.com> wrote:
> > Not that hard, perhaps.  What if, by the law of perverse solutions,
> > the backquote construct is implemented so that for `(,x) it does
> > a REPLACA on the cons produced by the reader when it processed the
> > opening parenthesis.  I'd like to be corrected that this is illegal.

> No I think you're right; a quick look at Steele suggests that anything EQUAL
> to (list x) would be OK here.

The critical thing is that (list x) conses fresh structure.
(eq (list x) (list x)) is guaranteed to yield false.
Not so for (eq (rplaca x 'a) (rplaca x 'b)), which yields true.

Further, if you changed the car of the cons which was (,x), where
would you remember the ,x part in case the form was evaluated
a second time?


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kent M Pitman  
View profile  
 More options Apr 27 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Kent M Pitman <pit...@world.std.com>
Date: 1999/04/27
Subject: Re: There has got to be a better way...

e...@liv.ac.uk (ey15) writes:
> I can't say if this one is simple or eligant, but it seams to work...

> (defun collapse-list (l)
>   (loop with result = (list nil)
>         with result-tail = result
>         for item in l
>         if (atom item)
>         do (rplacd result-tail (list item))
>            (setq result-tail (cdr result-tail))
>         else
>         do (rplacd result-tail (collapse-list item))
>            (setq result-tail (last result-tail))
>         end
>         finally return (cdr result)))

(defun collapse-list (list)
  (loop for item in list
        when (atom item)
         collect item
        else
         nconc (collapse-list item)))

does pretty much the same thing and with a good deal more perspicuity.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kent M Pitman  
View profile  
 More options Apr 27 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Kent M Pitman <pit...@world.std.com>
Date: 1999/04/27
Subject: Re: There has got to be a better way...
"Howard R. Stearns" <how...@elwood.com> writes:

> Kent M Pitman wrote:
> > ...  You want #'(lambda (x) (funcall fn x))
> > in situations like this.  [Or if you have the lisp machine's circular-list
> > function, (mapcar #'funcall (circular-list fn) lists).  Admittedly
> > obscure, but some use it idiomatically--almost to the point that I think
> > the compiler should have had an optimizer for it that turned it back
> > into something that didn't waste the single cons needed to make the circular
> > list.]

> What is circular-list?

(defun circular-list (&rest x)
  (nconc x x))

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
paul_rudin  
View profile  
 More options Apr 27 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: paul_ru...@scientia.com
Date: 1999/04/27
Subject: Re: There has got to be a better way...
In article <sfwiuaigmgi....@world.std.com>,
  Kent M Pitman <pit...@world.std.com> wrote:

I think we're at cross purposes: by "OK here" I was meant to say that any
such value would be a valid implementation for the result of the backquote
form, not that it would neccessarily be the right thing in the oringinal
function defn.

As you say, if mapcan is being used it is desirable that you have fresh lists.
My error was that I hadn't appreciated that the precise identity of the object
constructed by `(,x) is implementation dependent, provided it's EQUAL to
(list x).

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David D. Smith  
View profile  
 More options Apr 27 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: d...@flavors.com (David D. Smith)
Date: 1999/04/27
Subject: Re: There has got to be a better way...
In article <slrn7i2s0b.oj4.ktur...@pug1.sprocketshop.com>,
ktur...@pug1.sprocketshop.com (Kenneth P. Turvey) wrote:

> As part of another project I had need of a function to collapse a
> possibly nested list into an unnested version containing the same atoms.
> After finishing my first hack at it I thought, "There has got to be a
> better way".  I was hoping some of you Lisp experts (I'm mediocre in
> this language, at best) would be able to help me out.  I am not
> particularly concerned with performance.  I would like to see a simple
> and elegant solution.

...

Here is an iterative form to complement all the elegant recursive
solutions.  It  is pontentially less efficient.

(defun flatten (x)
  (do ((result nil)
       (last nil)
       (this (copy-list x)))
      ((null this) result)
    (if (listp (car this))
      (setq this (append (car this) (cdr this)))
      (setq last (if last
                   (setf (cdr last) this)
                   (setq result this))
            this (cdr this)))))

d


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vassil Nikolov  
View profile  
 More options Apr 28 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Vassil Nikolov <vniko...@poboxes.com>
Date: 1999/04/28
Subject: Re: There has got to be a better way...
In article <ey31zh7w6d3....@lostwithiel.tfeb.org>,
  Tim Bradshaw <t...@tfeb.org> wrote:
(...)
> Quite apart from being just
> wrong (sigh), my answer

(...)

Why?

--
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vassil Nikolov  
View profile  
 More options Apr 28 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Vassil Nikolov <vniko...@poboxes.com>
Date: 1999/04/28
Subject: Re: There has got to be a better way...
In article <7g2ccl$su...@nnrp1.dejanews.com>,
  Vassil Nikolov <vniko...@poboxes.com> wrote:

> Not that hard, perhaps.  What if, by the law of perverse solutions,
> the backquote construct is implemented so that for `(,x) it does
> a REPLACA on the cons produced by the reader when it processed the
> opening parenthesis.  I'd like to be corrected that this is illegal.

In article <sfwiuaigmgi....@world.std.com>,
  Kent M Pitman <pit...@world.std.com> wrote:

> The critical thing is that (list x) conses fresh structure.
> (eq (list x) (list x)) is guaranteed to yield false.
> Not so for (eq (rplaca x 'a) (rplaca x 'b)), which yields true.

Yes, but what in the language definition specifically implies that
`(,x) must be fresh?  (Apart from the fact that everybody knows
it is the Wrong Thing if it is not fresh.)

> Further, if you changed the car of the cons which was (,x), where
> would you remember the ,x part in case the form was evaluated
> a second time?

`(,X) must be read as a form which, when evaluated, produces a list
of one element which is the value of X, right?  (The canonical such
form is (LIST X).)  I had in mind reading that as the following form

  (progn (replaca #1=#:the-cons-the-reader-made x) #1#)

or something like that.  Evaluating this form evaluates X and
returns a list whose car is the value of X thus produced.

Once again: I am not advocating such a perverse way of doing it
(and can't think of a reason that would justify it); I just want
to learn if and how this is illegal (and not just ugly and
counterproductive).

--
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Stig Hemmer  
View profile  
 More options Apr 28 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Stig Hemmer <s...@pvv.ntnu.no>
Date: 1999/04/28
Subject: Re: There has got to be a better way...

Vassil Nikolov <vniko...@poboxes.com> writes:
> `(,X) must be read as a form which, when evaluated, produces a list
> of one element which is the value of X, right?  (The canonical such
> form is (LIST X).)  I had in mind reading that as the following form

>   (progn (replaca #1=#:the-cons-the-reader-made x) #1#)

> or something like that.  Evaluating this form evaluates X and
> returns a list whose car is the value of X thus produced.

Well, I can't say wether such an implementation would be technically
legal or not, but it sure would break a lot of existing code.

The problem is that a second call to this form would destroy the
result of the first one.  People tend to rely on this not happening.

If you read back you will find that Kent wasn't talking about
_legality_ but about _clearity_.

Consider `(,X Y).

An implementation could rewrite that as (CONS X '(Y)), with the '(Y)
being a shared constant.

In this case, a call to the form would not destroy previous results,
but it would still be a bad thing to give this to NCONC.

While it is hard to imagine `(,X) giving that sort of problems, it is
still good to use (LIST X) to make it clear to _human_ readers that we
want new structure.

Stig Hemmer,
Jack of a Few Trades.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kent M Pitman  
View profile  
 More options Apr 28 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Kent M Pitman <pit...@world.std.com>
Date: 1999/04/28
Subject: Re: There has got to be a better way...

Stig Hemmer <s...@pvv.ntnu.no> writes:
> Consider `(,X Y).

> An implementation could rewrite that as (CONS X '(Y)), with the '(Y)
> being a shared constant.

> In this case, a call to the form would not destroy previous results,
> but it would still be a bad thing to give this to NCONC.

> While it is hard to imagine `(,X) giving that sort of problems, it is
> still good to use (LIST X) to make it clear to _human_ readers that we
> want new structure.

This is exactly what I meant, yes.
Thanks for holding the fort while I'm working on my scifi novel...
Back to the grind.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tim Bradshaw  
View profile  
 More options Apr 28 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Tim Bradshaw <t...@tfeb.org>
Date: 1999/04/28
Subject: Re: There has got to be a better way...

* Vassil Nikolov wrote:
> In article <ey31zh7w6d3....@lostwithiel.tfeb.org>,
>   Tim Bradshaw <t...@tfeb.org> wrote:
> (...)
>> Quite apart from being just
>> wrong (sigh), my answer
> (...)
> Why?

Why was it wrong?  Because it didn't deal with NIL right as Kent
pointed out.  I make this mistake all the time.

--tim


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juanma Barranquero  
View profile  
 More options Apr 29 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: barranqu...@laley-actualidad.es (Juanma Barranquero)
Date: 1999/04/29
Subject: Re: There has got to be a better way...
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

>I am not particularly concerned with performance. I would like
>to see a simple and elegant solution.

OTOH, I tried to find a good one, performance-wise...

Of the solutions posted 'round here, the fastest (in my ACL 5.0 for
Windows, and with appropriate settings of optimize) was Pitman's:

(defun collapse-list (tree)
  (loop
      for item in tree
      when (atom item)
        collect item
      else
        nconc (collapse-list item)))

Mine, loosely based on Tim Bradshaw's code, is

(defun flatten-tree (tree &key preserve-nil (depth -1))
  (labels ((walk (branch level accum)
             (dolist (item branch accum)
               (if (atom item)
                   (when (or item preserve-nil)
                     (push item accum))
                 (if (zerop level)
                     (push (copy-tree item) accum)
                   (setq accum (walk item (1- level) accum)))))))
    (nreverse (walk tree depth '()))))

used as:

> USER(84): (setq *test* '(((a) nil) b (((c) d) (e (f (g nil))) nil (h (i)) nil)))
> (((A) NIL) B (((C) D) (E (F (G NIL))) NIL (H (I)) NIL))
> USER(85): (flatten-tree *test*)
> (A B C D E F G H I)
> USER(86): (flatten-tree *test* :preserve-nil t)
> (A NIL B C D E F G NIL NIL H I NIL)
> USER(87): (flatten-tree *test* :preserve-nil t :depth 1)
> ((A) NIL B ((C) D) (E (F (G NIL))) NIL (H (I)) NIL)
> USER(88): (flatten-tree *test* :preserve-nil nil :depth 1)
> ((A) B ((C) D) (E (F (G NIL))) (H (I)))
> USER(89): (flatten-tree *test* :preserve-nil t :depth 3)
> (A NIL B C D E F (G NIL) NIL H I NIL)
> USER(90):

which, in my tests (and using ":preserve-nil t" to be able to compare
it), is about 15-20% *slower* than Pitman's, but conses almost 40%
less.

All in all, it's been a lot of fun :)

                                                       /L/e/k/t/u

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 6.0.2i

iQA/AwUBNyhjTf4C0a0jUw5YEQLTqgCgywtJeJYkZkGomZ5fmAuG8cSoGnUAoJUx
TLlJhJWtPorBW+5REBaae61P
=DvuH
-----END PGP SIGNATURE-----


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kent M Pitman  
View profile  
 More options Apr 29 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Kent M Pitman <pit...@world.std.com>
Date: 1999/04/29
Subject: Re: There has got to be a better way...

barranqu...@laley-actualidad.es (Juanma Barranquero) writes:
> in my tests (and using ":preserve-nil t" to be able to compare
> it), is about 15-20% *slower* than Pitman's, but conses almost 40%
> less.

Uh, you should talk to Franz about why mine would not do optimal consing.
I don't see any gratuitous consing in the source code.  I see no reason
LOOP shouldn't be able to do a completely optimal job on that part.

And make sure you don't use keyword argument passing when doing any of
this, because that's going to potentially dwarf the time spent doing
the other parts.  I haven't seen how Franz compiles them, and I'm just
speaking generally about the language, but while keyword calls buy
important flexibilty in non-mission-critical interfaces, and some
people (e.g. Paul Graham) are big fans of their use in a great many
situations, they are real potentials for slow code in tight loops and
the decision to use them for code maintenance reasons has to be traded
against the potential difficulty of compiling them efficiently.  Most
compilers I've used could do a lot better than they do in compiling
keyword calls than they do, too, so you're often not even seeing
optimal treatment.  I'm pretty sure CLIM, for example, has massive
numbers of compiler macros to try to get those keyword calls out of
the runtime code because it's such a potential bottleneck.  Compiler
macros were added to CL specifically to help in such cases.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vassil Nikolov  
View profile  
 More options Apr 30 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Vassil Nikolov <vniko...@poboxes.com>
Date: 1999/04/30
Subject: Re: There has got to be a better way...
In article <ekv4sm1t4n5....@ra.pvv.ntnu.no>,
  Stig Hemmer <s...@pvv.ntnu.no> wrote:

> Vassil Nikolov <vniko...@poboxes.com> writes:
> > `(,X) must be read as a form which, when evaluated, produces a list
> > of one element which is the value of X, right?  (The canonical such
> > form is (LIST X).)  I had in mind reading that as the following form

> >   (progn (replaca #1=#:the-cons-the-reader-made x) #1#)

> > or something like that.  Evaluating this form evaluates X and
> > returns a list whose car is the value of X thus produced.

> Well, I can't say wether such an implementation would be technically
> legal or not, but it sure would break a lot of existing code.

> The problem is that a second call to this form would destroy the
> result of the first one.  People tend to rely on this not happening.

I did write `perverse,' `ugly,' *and* `counterproductive,' didn't I?

> If you read back you will find that Kent wasn't talking about
> _legality_ but about _clearity_.

Indeed he wasn't; it was me who took the occasion to ask about
legality.

> Consider `(,X Y).

> An implementation could rewrite that as (CONS X '(Y)), with the '(Y)
> being a shared constant.

A literal constant that may be shared, you mean, of course.

> In this case, a call to the form would not destroy previous results,
> but it would still be a bad thing to give this to NCONC.

> While it is hard to imagine `(,X) giving that sort of problems, it is
> still good to use (LIST X) to make it clear to _human_ readers that we
> want new structure.

Absolutely.  Now, back to my question:

Can you or anyone confirm or contradict that the above RPLACA implementation
is legal?  If it is, it might break people's code, but people should
not rely on implementations not doing legal things, shouldn't they?
Please understand me correctly: I'd rather have that illegal, but I
can't see it illegal in the language specification.

--
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vassil Nikolov  
View profile  
 More options Apr 30 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Vassil Nikolov <vniko...@poboxes.com>
Date: 1999/04/30
Subject: Re: There has got to be a better way...
In article <ey3btg9b2lc....@lostwithiel.tfeb.org>,
  Tim Bradshaw <t...@tfeb.org> wrote:

> * Vassil Nikolov wrote:
> > In article <ey31zh7w6d3....@lostwithiel.tfeb.org>,
> >   Tim Bradshaw <t...@tfeb.org> wrote:
> > (...)
> >> Quite apart from being just
> >> wrong (sigh), my answer
> > (...)

> > Why?

> Why was it wrong?  Because it didn't deal with NIL right as Kent
> pointed out.  I make this mistake all the time.

Thanks for replying.  I thought I had missed some real bug.  The
way your solution dealt with NIL may or may not be wrong---depends
on the purpose.  And it is not difficult to change it from one
functionality to the other.

--
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juanma Barranquero  
View profile  
 More options Apr 30 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: barranqu...@laley-actualidad.es (Juanma Barranquero)
Date: 1999/04/30
Subject: Re: There has got to be a better way...
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Thu, 29 Apr 1999 15:22:46 GMT, Kent M Pitman <pit...@world.std.com>
wrote:

>Uh, you should talk to Franz about why mine would not do optimal
>consing. I don't see any gratuitous consing in the source code.  I
>see no reason LOOP shouldn't be able to do a completely optimal job
>on that part.

Well, there's definitely a difference in consing between the two
functions.

I've now tested with:

; my function, simplified to have the same interface as yours
(defun flatten-tree (tree)
  (labels ((walk (branch accum)
             (dolist (item branch accum)
               (if (atom item)
                   (push item accum)
                 (setq accum (walk item accum))))))
    (nreverse (walk tree '()))))

; your function
(defun collapse-list (tree)
  (loop
      for item in tree
      when (atom item)
        collect item
      else
        nconc (collapse-list item)))

and the following test data (not very significative, I know):

nil
(nil)
((((((((((((((((((((a))))))))))))))))))))
(a b c d e f g h i j k l m n o p q r s t u v w x y z)
((((((((((a) b) c) d) e) f) g) h) i) j)
(a (b (c (d (e (f (g (h (i (j))))))))))
(((((((((((a)))))))))) ((((((((((b)))))))))))
(a (b (c (d (e (f (g (h (i) j) k) l) m) n) o) p) q)
(a nil (b ((c d (nil) e (f (g) h) nil) (i j) k) l) (((m))) nil)
((j u a n m a) (b a r r a n q u e r o)))

in a 1,000,000 iterations loop. The results I get, with

(optimize (speed 3) (space 1) (safety 0) (debug 0))

are:

USER(30): (time (test-fun1))  ;; flatten-tree
; cpu time (non-gc) 92,738 msec (00:01:32.738) user, 0 msec system
; cpu time (gc)     10,621 msec user, 0 msec system
; cpu time (total)  103,359 msec (00:01:43.359) user, 0 msec system
; real time  103,358 msec (00:01:43.358)
; space allocation:
;  101,001,351 cons cells, 0 symbols, 4,928 other bytes, 0 static
bytes

USER(34): (time (test-fun2))  ;; collapse-list
; cpu time (non-gc) 92,904 msec (00:01:32.904) user, 0 msec system
; cpu time (gc)     19,808 msec user, 0 msec system
; cpu time (total)  112,712 msec (00:01:52.712) user, 0 msec system
; real time  112,712 msec (00:01:52.712)
; space allocation:
;  188,000,000 cons cells, 0 symbols, 5,312 other bytes, 0 static
bytes

so they're about equal in speed but mine consed 54% of what yours did.
I sure don't know why. Maybe Duane Retting is reading us and can offer
any hint?

>And make sure you don't use keyword argument passing when doing any
>of this, because that's going to potentially dwarf the time spent
>doing the other parts.

Thanks for your informative post about keyword arguments. I didn't
know any of that.

                                                       /L/e/k/t/u

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 6.0.2i

iQA/AwUBNyl3Jv4C0a0jUw5YEQIPZACglxjTRVDwnSHwAT/4gHJk9MLaI8YAoL5X
Bh0m1l5Mjsm9ocCcuhW0JG4y
=t6Jc
-----END PGP SIGNATURE-----


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Bernhard Pfahringer  
View profile  
 More options Apr 30 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: bernh...@hummel.ai.univie.ac.at (Bernhard Pfahringer)
Date: 1999/04/30
Subject: Re: There has got to be a better way...
In article <372a71f2.60523...@news.mad.ttd.net>,

Juanma Barranquero <barranqu...@laley-actualidad.es> wrote:

>Well, there's definitely a difference in consing between the two
>functions.

>(defun collapse-list (tree)
>  (loop
>      for item in tree
>      when (atom item)
>        collect item
>      else
>        nconc (collapse-list item)))

The difference in consing is probably explained by the way (I suppose)
loop COLLECTs values without doing nreverse. It probably destructively
modifies the tail of the result list, which itself is initialized using
one cons-cell to simplify the update code. Consequently, you'd get an
overhead of one additional cons-cell per call. Depending on the details,
the overhead could as well be more than one cell. Looking at the
macro-expanded code might further clarify this issue. But anyway, the
additional consing seems worth (cf. runtimes). There once was this
slogan "Consing is cheap", which I think should be rephrased into
"Consing can be cheap" (given you know what you do and have a well-
implemented generational garbage collector at your disposal).

A problem with all solutions proposed so far is recursion over the
substructures which is not tail-recursive. So the call stack might overflow
for deep enough structures. The following iterative version manages its own
stack (including tail-recursion optimization). As only each non-last-position
substructure necessitates a stack-push, this version will never cons more than
the original loop-based one.

(defun collapse-list (list)
  (loop with stack = nil
        for item = (cond (list (pop list))
                         (stack (setq list (pop stack))
                                (pop list))
                         (t (loop-finish)))
        if (atom item)
         collect item
        else
         do (when list
               (push list stack))
            (setf list item)))

Bernhard
--
--------------------------------------------------------------------------
Bernhard Pfahringer
Austrian Research Institute for  http://www.ai.univie.ac.at/~bernhard/
Artificial Intelligence          bernh...@ai.univie.ac.at


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Juanma Barranquero  
View profile  
 More options Apr 30 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: barranqu...@laley-actualidad.es (Juanma Barranquero)
Date: 1999/04/30
Subject: Re: There has got to be a better way...
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 30 Apr 1999 13:22:13 GMT, bernh...@hummel.ai.univie.ac.at (Bernhard

Pfahringer) wrote:
>But anyway, the additional consing seems worth (cf. runtimes).

Not in my example, as both routines were approx. equal in speed.

>A problem with all solutions proposed so far is recursion over the
>substructures which is not tail-recursive. So the call stack might
>overflow for deep enough structures.

Yes, you're right. I tried an iterative version, but it wasn't half as
clever as yours (nor half as obscure, OTOH ;)

>The following iterative version manages its own stack (including
>tail-recursion optimization). As only each non-last-position
>substructure necessitates a stack-push, this version will never cons
>more than the original loop-based one.

It stills conses (in my Allegro) about 36% more than my best recursive
version, but is also 44% faster, and as you say it doesn't have to
worry about stack depth. Pretty impressive. Thanks.

                                                       /L/e/k/t/u

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 6.0.2i

iQA/AwUBNym0of4C0a0jUw5YEQJZPgCdG8XfZCB2M8adHE4sv1wn9dFhw1EAoObT
UrZR6WgQFRHip8eUPKoArsk6
=zEDG
-----END PGP SIGNATURE-----


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 26 - 50 of 73 < Older  Newer >
« Back to Discussions « Newer topic     Older topic »