Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

Disclaimer: "These opinions are my own, though for a small fee they be yours too." -- Dave Haynie


devel / comp.lang.scheme / Re: (iota N) in Spice Lisp idiom

SubjectAuthor
* (iota N) in Spice Lisp idiomHenHanna
+- Re: (iota N) in Spice Lisp idiomLawrence D'Oliveiro
+- Re: (iota N) in Spice Lisp idiomKaz Kylheku
`* Re: (iota N) in Spice Lisp idiomPaul Rubin
 `* Re: (iota N) in Spice Lisp idiomKaz Kylheku
  `* Re: (iota N) in Spice Lisp idiomPaul Rubin
   `* Re: (iota N) in Spice Lisp idiomKaz Kylheku
    `* Re: (iota N) in Spice Lisp idiomPaul Rubin
     `* Re: (iota N) in Spice Lisp idiomAlan Bawden
      `- Re: (iota N) in Spice Lisp idiomPaul Rubin

1
(iota N) in Spice Lisp idiom

<urlpb6$3esh4$1@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=291&group=comp.lang.scheme#291

  copy link   Newsgroups: comp.lang.lisp comp.lang.scheme
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: HenHanna@gmail.com (HenHanna)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: (iota N) in Spice Lisp idiom
Date: Tue, 27 Feb 2024 14:56:39 -0800
Organization: A noiseless patient Spider
Lines: 18
Message-ID: <urlpb6$3esh4$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 27 Feb 2024 22:56:39 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="dbfb73302111358856141c2acd36e691";
logging-data="3633700"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/dBIudK03+UMj8Sf7U+2101Z8fAowbQh0="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:sEaR/YIfTYO08JjKMhR8Gh8113A=
Content-Language: en-US
 by: HenHanna - Tue, 27 Feb 2024 22:56 UTC

>>> (define (range n) ; returns a list of integers [0 ... n-1]

When i was young, i studied Spice Lisp source code from CMU.
Where are they (Skef, Rob, ...) now?

They almost-always used this idiom of Push, Push, ... Nreverse.

e.g. for (iota N)

(do ((res nil)
(n 100 (1- n))
.....)
((zerop n) ... (nreverse res))

(push n res))

Re: (iota N) in Spice Lisp idiom

<urlqav$3ep9p$8@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=292&group=comp.lang.scheme#292

  copy link   Newsgroups: comp.lang.lisp comp.lang.scheme
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: ldo@nz.invalid (Lawrence D'Oliveiro)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: (iota N) in Spice Lisp idiom
Date: Tue, 27 Feb 2024 23:13:35 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 5
Message-ID: <urlqav$3ep9p$8@dont-email.me>
References: <urlpb6$3esh4$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 27 Feb 2024 23:13:35 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="2b5f550de027bed53e7de3d0720ccb3e";
logging-data="3630393"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX198xgeq1RNma7xqw2vnSoCM"
User-Agent: Pan/0.155 (Kherson; fc5a80b8)
Cancel-Lock: sha1:CkePQoKtCW4GeNGZLbUKun1Isks=
 by: Lawrence D'Oliv - Tue, 27 Feb 2024 23:13 UTC

On Tue, 27 Feb 2024 14:56:39 -0800, HenHanna wrote:

> They almost-always used this idiom of Push, Push, ... Nreverse.

Neither are available in Guile, that I can see.

Re: (iota N) in Spice Lisp idiom

<20240227155052.547@kylheku.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=293&group=comp.lang.scheme#293

  copy link   Newsgroups: comp.lang.lisp comp.lang.scheme
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: 433-929-6894@kylheku.com (Kaz Kylheku)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: (iota N) in Spice Lisp idiom
Date: Wed, 28 Feb 2024 00:06:03 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 36
Message-ID: <20240227155052.547@kylheku.com>
References: <urlpb6$3esh4$1@dont-email.me>
Injection-Date: Wed, 28 Feb 2024 00:06:03 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="8db9a85693c796a45b822e4215883be9";
logging-data="3663999"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18Nd68l2BLeOBp7g1juOO+Mz3eafveS5Ac="
User-Agent: slrn/pre1.0.4-9 (Linux)
Cancel-Lock: sha1:ub/JYn4ik+q5z1FpeRo7kDu265E=
 by: Kaz Kylheku - Wed, 28 Feb 2024 00:06 UTC

On 2024-02-27, HenHanna <HenHanna@gmail.com> wrote:
>
> >>> (define (range n) ; returns a list of integers [0 ... n-1]
>
> When i was young, i studied Spice Lisp source code from CMU.
> Where are they (Skef, Rob, ...) now?
>
> They almost-always used this idiom of Push, Push, ... Nreverse.

Yes, that idiom is still used in Common Lisp and similar dialects.

There are other tools; here are some.

Common Lisp's loop macro has a collect{ing} clause.

(defun iota (n)
(loop for i from i to n
collect n))

Guy Steele describes, in CLTL2, a module which supports procedural
list construction. See the "Generators and Gatherers" appendix chapter.
This is not in Common Lisp.

(let ((g (gatherer #'collect)))
(next-out g 1)
(next-out g 2)
(next-out g 3)
(result-of g))
-> (1 2 3)

If you use (gatherer #'collect-sum) you will get 6.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

Re: (iota N) in Spice Lisp idiom

<875xy9e740.fsf@nightsong.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=294&group=comp.lang.scheme#294

  copy link   Newsgroups: comp.lang.lisp comp.lang.scheme
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: no.email@nospam.invalid (Paul Rubin)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: (iota N) in Spice Lisp idiom
Date: Tue, 27 Feb 2024 16:59:43 -0800
Organization: A noiseless patient Spider
Lines: 15
Message-ID: <875xy9e740.fsf@nightsong.com>
References: <urlpb6$3esh4$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="b11dea1ec4537807cb9ed89e3ac624c7";
logging-data="3681216"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19n3jfby6ZDfoA/ptAqitEv"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)
Cancel-Lock: sha1:RGsELcL67AZd7PYFRJ92G5Dd5VY=
sha1:qRn1V8E4//LtR5Ufbf491WfOdBM=
 by: Paul Rubin - Wed, 28 Feb 2024 00:59 UTC

HenHanna <HenHanna@gmail.com> writes:
> They almost-always used this idiom of Push, Push, ... Nreverse.

That is an old school Lisp thing, I think. Scheme tends to frown on
mutation, though it has reverse! which can destructively reverse lists
that you explicitly built using cons.

It was before my time but I think historically, mutation (nreverse,
rplaca/rplacd, etc.) was more important in machines that were starved
for memory. Once memory got bigger, it tended to get used primarily for
caches, images, numerical arrays, and other pointer-free data that
didn't need to be garbage collected, and you didn't have to worry as
much about squeezing the size of your program heap. Another sign of
that change was switching to semispace garbage collectors from intricate
BIBOP or similar schemes.

Re: (iota N) in Spice Lisp idiom

<20240227171434.812@kylheku.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=295&group=comp.lang.scheme#295

  copy link   Newsgroups: comp.lang.lisp comp.lang.scheme
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: 433-929-6894@kylheku.com (Kaz Kylheku)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: (iota N) in Spice Lisp idiom
Date: Wed, 28 Feb 2024 01:29:51 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 50
Message-ID: <20240227171434.812@kylheku.com>
References: <urlpb6$3esh4$1@dont-email.me> <875xy9e740.fsf@nightsong.com>
Injection-Date: Wed, 28 Feb 2024 01:29:51 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="8db9a85693c796a45b822e4215883be9";
logging-data="3691104"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/LYgjgOIj7ax4/+TpiqE9oOHzHVeROiBs="
User-Agent: slrn/pre1.0.4-9 (Linux)
Cancel-Lock: sha1:ubmJ313iG1F5VsZHqOStT00kdsA=
 by: Kaz Kylheku - Wed, 28 Feb 2024 01:29 UTC

On 2024-02-28, Paul Rubin <no.email@nospam.invalid> wrote:
> HenHanna <HenHanna@gmail.com> writes:
>> They almost-always used this idiom of Push, Push, ... Nreverse.
>
> That is an old school Lisp thing, I think. Scheme tends to frown on
> mutation, though it has reverse! which can destructively reverse lists
> that you explicitly built using cons.
>
> It was before my time but I think historically, mutation (nreverse,
> rplaca/rplacd, etc.) was more important in machines that were starved
> for memory. Once memory got bigger, it tended to get used primarily for
> caches, images, numerical arrays, and other pointer-free data that
> didn't need to be garbage collected, and you didn't have to worry as
> much about squeezing the size of your program heap. Another sign of
> that change was switching to semispace garbage collectors from intricate
> BIBOP or similar schemes.

If you don't think performance is important, you can use non-destructive
reverse. A list can be built in reverse without mutating a variable,
using tail recursion, and then reversed by constructing a new list,
so that everything is purely funtional.

For instance, here is a tail-recursive mapcar that explicitly passes the
stack of items pushed so far:

(defun map (fn list &optional so-far)
(if (null list)
(reverse so-far)
(map fn
(cdr list)
(cons (funcall fn (car list)) so-far))))

nreverse is used when it is obvious that the cells allocated to the
reversed list have not been shared with the rest of the program.

If those cells are not are not returned to the caller, but only used
as a template for creating a reversed list, those original cells
immediately become garbage.

If the function itself has allocated the reverse list, it can build the
forward list out of those original cells without breaking anything.

Destructive reverse remains a current technique in manipulation of
cons-based lists. It can make a measurable difference on a 3 GHz
machine just like on a 30 MHz machine.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

Re: (iota N) in Spice Lisp idiom

<87wmqpcpzr.fsf@nightsong.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=297&group=comp.lang.scheme#297

  copy link   Newsgroups: comp.lang.lisp comp.lang.scheme
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: no.email@nospam.invalid (Paul Rubin)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: (iota N) in Spice Lisp idiom
Date: Tue, 27 Feb 2024 17:54:48 -0800
Organization: A noiseless patient Spider
Lines: 26
Message-ID: <87wmqpcpzr.fsf@nightsong.com>
References: <urlpb6$3esh4$1@dont-email.me> <875xy9e740.fsf@nightsong.com>
<20240227171434.812@kylheku.com>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="b11dea1ec4537807cb9ed89e3ac624c7";
logging-data="3696691"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19BiG6NXNMfcyZEMKQbbeMt"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)
Cancel-Lock: sha1:74wSMSwvu1QqAKKPXuP0wYEcc6U=
sha1:0jihs7e8GQ9BKgJ+Cu0EpRqIdnY=
 by: Paul Rubin - Wed, 28 Feb 2024 01:54 UTC

Kaz Kylheku <433-929-6894@kylheku.com> writes:
> For instance, here is a tail-recursive mapcar that explicitly passes the
> stack of items pushed so far:...

That is Lisp, not Scheme. It's possible that some similar looking code
would work in Scheme, but I notice that Scheme seems to distinguish
explicitly consed lists from e.g. quoted lists. reverse! in my
experiments only seems to work on explicitly consed lists.

If the lists are large, I think idiomatically in Scheme one would tend
to use lazy streams (implemented with force and delay) rather than
building and reversing an entire intermediate list. Then you would
generate the mapped elements in order. I expect there are SRFI's for
this but I'm not that familiar with them. Of course in Haskell the
laziness is built into the language.

> Destructive reverse remains a current technique in manipulation of
> cons-based lists. It can make a measurable difference on a 3 GHz
> machine just like on a 30 MHz machine.

As always, justifying such a claim about any particular application
requires benchmarking that application with both reversal methods. The
application might not spend much of its time reversing lists. Even if
it does, the wider implementation is then suspect, because large lists
tend to have poor memory locality. You might look to instead use
generators, or packed vectors, or whatever.

Re: (iota N) in Spice Lisp idiom

<20240227175953.324@kylheku.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=298&group=comp.lang.scheme#298

  copy link   Newsgroups: comp.lang.lisp comp.lang.scheme
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: 433-929-6894@kylheku.com (Kaz Kylheku)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: (iota N) in Spice Lisp idiom
Date: Wed, 28 Feb 2024 02:53:14 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 110
Message-ID: <20240227175953.324@kylheku.com>
References: <urlpb6$3esh4$1@dont-email.me> <875xy9e740.fsf@nightsong.com>
<20240227171434.812@kylheku.com> <87wmqpcpzr.fsf@nightsong.com>
Injection-Date: Wed, 28 Feb 2024 02:53:14 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="8db9a85693c796a45b822e4215883be9";
logging-data="3718841"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19e/raSOuJN6AQwUoWVUjbQTOAzLrVaIzY="
User-Agent: slrn/pre1.0.4-9 (Linux)
Cancel-Lock: sha1:4FzokcejurHgSL0mwupA6Ajz2KQ=
 by: Kaz Kylheku - Wed, 28 Feb 2024 02:53 UTC

On 2024-02-28, Paul Rubin <no.email@nospam.invalid> wrote:
> Kaz Kylheku <433-929-6894@kylheku.com> writes:
>> For instance, here is a tail-recursive mapcar that explicitly passes the
>> stack of items pushed so far:...
>
> That is Lisp, not Scheme. It's possible that some similar looking code
> would work in Scheme, but I notice that Scheme seems to distinguish
> explicitly consed lists from e.g. quoted lists. reverse! in my
> experiments only seems to work on explicitly consed lists.

In Common Lisp, modifying quoted lists is undefined behavior.

This would not arise in code that builds a dynamic list in reverse.

> If the lists are large, I think idiomatically in Scheme one would tend
> to use lazy streams (implemented with force and delay) rather than
> building and reversing an entire intermediate list. Then you would
> generate the mapped elements in order. I expect there are SRFI's for
> this but I'm not that familiar with them. Of course in Haskell the
> laziness is built into the language.

In a well built Common Lisp implementation, all the library functions
that accumulate lists, like mapcar or the collect clause of Loop and
whatnot, can be reasonably expected not to just push conses onto a stack
and then nreverse. Typically, a tail pointer is maintained and the last
cons cell is mutated to add the next one.

There is a way to do this with a single variable. We accumulate
a circular list, keeping a pointer to its tail cons cell, which points
to the head. For each new item, we make the tail point to a new
cell, such that that cell points to the head. When we are done, we
replace the head pointer with the terminating object, () or nil or
whatever it is in that Lisp dialect.

E.g. in our tail-recursive map, we can pass a context that is the
tail of the circular list:

(defun get-result (tail)
(if tail
(prog1 (cdr tail) ;; (cdr tail) is the head we are returning
(rplacd tail nil)))) ;; clobbered with nil to terminate list

(defun collect (tail item)
(if tail
;; non-empty case: add into circular list after tail
(let* ((head (cdr tail))
(ntail (cons item head)))
(rplacd tail ntail)
ntail))
;; empty case: create new head node, pointing to itself
(let ((ntail (cons item nil)))
(rplacd ntail ntail)
ntail))

(defun map (fn list &optional tail)
(if (null list)
(get-result tail)
(map fn
(cdr list)
(collect tail (funcall fn (car list))))))

If we write:

(defun get-result (x) (reverse x))
(defun collect (x y) (cons y x))

we get the original implementation.

>> Destructive reverse remains a current technique in manipulation of
>> cons-based lists. It can make a measurable difference on a 3 GHz
>> machine just like on a 30 MHz machine.
>
> As always, justifying such a claim about any particular application
> requires benchmarking that application with both reversal methods. The
> application might not spend much of its time reversing lists.

This is tricky because a function that generates garbage can increase
garbage collection time later, after that function is no longer running.

(And there are times when that's a good thing, like if the image
terminates before that GC ever happens, so the time is never spent.)

Typically in Lisps we have a profiling function which tells us how
much time was spent in some code, and how much memory was allocated.

If one stays the same, lowering the other one is better. If both
drop, that's a win.

You will rarely see a situation where an improvement in a function
resulting in less bytes consed, and less time, will be worse (more time
is spent somewhere else, cleaning-up after the function).

A counterexample might be a function that obtains a speedup via
memoization/caching. Once the cache is warmed up, it is fast, and conses
little memory, but the cache sticks around, and causes the garbage
collector to sometimes have to visit a larger reachable graph.

> Even if
> it does, the wider implementation is then suspect, because large lists
> tend to have poor memory locality. You might look to instead use
> generators, or packed vectors, or whatever.

Sure, but that is more work compared to a minor decision of whether
to drop-in replace reverse with nreverse, or other similar decisions
that have to do with "basic tidiness".

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

Re: (iota N) in Spice Lisp idiom

<87sf1dcjsv.fsf@nightsong.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=299&group=comp.lang.scheme#299

  copy link   Newsgroups: comp.lang.lisp comp.lang.scheme
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: no.email@nospam.invalid (Paul Rubin)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: (iota N) in Spice Lisp idiom
Date: Tue, 27 Feb 2024 20:08:32 -0800
Organization: A noiseless patient Spider
Lines: 38
Message-ID: <87sf1dcjsv.fsf@nightsong.com>
References: <urlpb6$3esh4$1@dont-email.me> <875xy9e740.fsf@nightsong.com>
<20240227171434.812@kylheku.com> <87wmqpcpzr.fsf@nightsong.com>
<20240227175953.324@kylheku.com>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="2e072082ce3eb36535e0d803303ef55f";
logging-data="3864762"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+8UzfpziJAEUNyxw3EEOFN"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)
Cancel-Lock: sha1:jgTkVInys3x9ro+4+ym/l0ErckU=
sha1:Arn8ejVqQBeHQIVp0fXTVsOwSqY=
 by: Paul Rubin - Wed, 28 Feb 2024 04:08 UTC

Kaz Kylheku <433-929-6894@kylheku.com> writes:
> In a well built Common Lisp implementation, all the library functions
> that accumulate lists, like mapcar or the collect clause of Loop and
> whatnot, can be reasonably expected not to just push conses onto a stack
> and then nreverse. Typically, a tail pointer is maintained and the last
> cons cell is mutated to add the next one.

Sure, but that still builds the list in memory before processing it,
instead of making a pipeline that generates, processes, and garbage
collects elements.

> There is a way to do this with a single variable. We accumulate
> a circular list, keeping a pointer to its tail cons cell

There is a cute way to do nreverse with three registers that is possibly
faster than messing with a tail pointer, in the absence of cache
effects.

> Sure, but that is more work compared to a minor decision of whether
> to drop-in replace reverse with nreverse, or other similar decisions
> that have to do with "basic tidiness".

I'll believe nreverse is faster for application X when I see a benchmark
showing it. It's not a matter of a definite gain that might be
negligible. Nreverse might actually slow the program down, since it
results in new conses pointing to older ones, which can cause fallback
behaviour in some generational gc schemes.

Regarding your 3 ghz vs 30 ghz computer example, see:

https://cr.yp.to/talks/2015.04.16/slides-djb-20150416-a4.pdf

Basically the 30 ghz computer likely won't be running the same programs
(or anyway the same inputs) as the 3 ghz one. The faster machine makes
it possible to handle bigger problems, and the execution profile will
change. Look at the stupendous number of cpu cycles going to whatever
bitmap display you're reading with right now, compated with old-school
character terminals.

Re: (iota N) in Spice Lisp idiom

<8634tdqge1.fsf@williamsburg.bawden.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=300&group=comp.lang.scheme#300

  copy link   Newsgroups: comp.lang.lisp comp.lang.scheme
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!bawden.eternal-september.org!.POSTED!not-for-mail
From: alan@csail.mit.edu (Alan Bawden)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: (iota N) in Spice Lisp idiom
Date: Wed, 28 Feb 2024 00:58:30 -0500
Organization: ITS Preservation Society
Lines: 26
Message-ID: <8634tdqge1.fsf@williamsburg.bawden.org>
References: <urlpb6$3esh4$1@dont-email.me> <875xy9e740.fsf@nightsong.com>
<20240227171434.812@kylheku.com> <87wmqpcpzr.fsf@nightsong.com>
<20240227175953.324@kylheku.com> <87sf1dcjsv.fsf@nightsong.com>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: bawden.eternal-september.org; posting-host="1384c6164665d5793836aae1bf2d2f55";
logging-data="3899814"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18R0cmafoQBZEiSb+hTjHWY"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux)
Cancel-Lock: sha1:3HEo8ik4iDAfDGqvynb+6hzmAFA=
sha1:oRp/Sw7HFczSUwCS448HdWMpCI4=
 by: Alan Bawden - Wed, 28 Feb 2024 05:58 UTC

Paul Rubin <no.email@nospam.invalid> writes:

I'll believe nreverse is faster for application X when I see a benchmark
showing it. It's not a matter of a definite gain that might be
negligible. Nreverse might actually slow the program down, since it
results in new conses pointing to older ones, which can cause fallback
behaviour in some generational gc schemes.

NREVERSE is not required to re-use the original cons cells in any
particular way. In fact, NREVERSE can do exactly the same thing as
REVERSE if an implementation determines that there is nothing better
that it can do. NREVERSE just gives the implementation permission to
re-use the old strucure, it doesn't force the implementation to do so.
So it's a good bet that using NREVERSE, whenever it is safe to do so,
will result in better performance.

Of course there might always be _some_ application where changing
NREVERSE to REVERSE will improve performance, but that's not going to be
the common case in a high quality Common Lisp implementation.

Always use NREVERSE (where you can) because in the unlikely event that
that proves to be the wrong choice, you can _always_ change it to plain
REVERSE without worry. (And in practice, I don't think that has ever
happened to me!)

- Alan

Re: (iota N) in Spice Lisp idiom

<87o7c1cd3g.fsf@nightsong.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=301&group=comp.lang.scheme#301

  copy link   Newsgroups: comp.lang.lisp comp.lang.scheme
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: no.email@nospam.invalid (Paul Rubin)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: (iota N) in Spice Lisp idiom
Date: Tue, 27 Feb 2024 22:33:23 -0800
Organization: A noiseless patient Spider
Lines: 23
Message-ID: <87o7c1cd3g.fsf@nightsong.com>
References: <urlpb6$3esh4$1@dont-email.me> <875xy9e740.fsf@nightsong.com>
<20240227171434.812@kylheku.com> <87wmqpcpzr.fsf@nightsong.com>
<20240227175953.324@kylheku.com> <87sf1dcjsv.fsf@nightsong.com>
<8634tdqge1.fsf@williamsburg.bawden.org>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="2e072082ce3eb36535e0d803303ef55f";
logging-data="3912390"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18T5TLDr/5exQPvnYqpjMQW"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)
Cancel-Lock: sha1:Z21KfJqSxggch7C5+lRiXC8tCq0=
sha1:E97bKaurUpaiyaNrVkTlD1cq+3M=
 by: Paul Rubin - Wed, 28 Feb 2024 06:33 UTC

Alan Bawden <alan@csail.mit.edu> writes:
> NREVERSE is not required to re-use the original cons cells in any
> particular way. In fact, NREVERSE can do exactly the same thing as
> REVERSE if an implementation determines that there is nothing better
> that it can do.

Oh interesting, I didn't realize that. I see that reverse! in Guile
throws exceptions if it doesn't like the conses that you give it. I'd
expet the compiler can also replace REVERSE with NREVERSE if it can
prove that the difference is not observable.

> Always use NREVERSE (where you can) because in the unlikely event that
> that proves to be the wrong choice, you can _always_ change it to plain
> REVERSE without worry.

Fair enough, NREVERSE in Lisp is certainly idiomatic. I don't know
whether reverse! is equally idiomatic in Scheme. Python tends to prefer
vectors or generators while Haskell uses generators for everything.

Here's an old talk by Guy Steele about Fortress, suggesting that lists
(and generators) in a context like this are an antipattern:

http://groups.csail.mit.edu/mac/users/gjs/6.945/readings/MITApril2009Steele.pdf

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor