unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: ludo@gnu.org (Ludovic Courtès)
To: guile-devel@gnu.org
Subject: Re: for-each et al
Date: Sun, 02 Mar 2014 22:27:52 +0100	[thread overview]
Message-ID: <87r46ks33b.fsf@gnu.org> (raw)
In-Reply-To: 87txbgr3wx.fsf@pobox.com

Hello!

Welcome back to email.  ;-)

Andy Wingo <wingo@pobox.com> skribis:

> The current boot-9 for-each for one list argument is this nastiness:
>
>   (define for-each
>     (case-lambda
>       ((f l)
>        (let for-each1 ((hare l) (tortoise l))
>          (if (pair? hare)
>              (begin
>                (f (car hare))
>                (let ((hare (cdr hare)))
>                  (if (pair? hare)
>                      (begin
>                        (when (eq? tortoise hare)
>                          (scm-error 'wrong-type-arg "for-each" "Circular list: ~S"
>                                     (list l) #f))
>                        (f (car hare))
>                        (for-each1 (cdr hare) (cdr tortoise)))
>                      (for-each1 hare tortoise))))
>              (if (not (null? hare))
>                  (scm-error 'wrong-type-arg "for-each" "Not a list: ~S"
>                             (list l) #f)))))
>       ...))
>
> Terrible.  And it's slower than this:
>
>   (lambda (f l)
>     (unless (list? l)
>       (scm-error 'wrong-type-arg "for-each" "Not a list: ~S" (list l) #f))
>     (let for-each1 ((l l))
>       (unless (null? l)
>         (f (car l))
>         (for-each1 (cdr l)))))
>
> So, pop quiz: what's the difference between the two?

I think an important difference you didn’t mention is that ‘list?’ does
its list traversal in C.

> Of course, there are different levels at which this problem can be
> solved.  I think moving towards deprecation and removal of mutable pairs
> is probably a good idea, though it's really complicated and not really
> the point of this mail.  OTOH I think it's reasonable to ask for a
> consensus opinion on this implementation of "for-each":
>
>   (lambda (f l)
>     (unless (list? l)
>       (scm-error 'wrong-type-arg "for-each" "Not a list: ~S" (list l) #f))
>     (let for-each1 ((l l))
>       (unless (null? l)
>         (f (car l))
>         (for-each1 (cdr l)))))
>
> Is this a reasonable implementation?  Are we OK with the possibility for
> infinite-loops or exceptions accessing the car/cdr of what might not be
> a pair?  Alternately if we change the test to pair? are we OK with the
> possibility of the loop possibly ending silently before its time?  How
> do we deal with this kind of bug -- what's our perspective?

I’m OK with this implementation.  I’ve never found myself iterating over
a list and modifying it concurrently.

> My proposal would be that eventually, I don't know how, but Guile should
> remove all use of mutable pairs in its own code.  There's not much
> set-car!/set-cdr! in Scheme so it's not that big of a deal.  Therefore
> in light of that long-term goal, we should write library code as if
> pairs were immutable, and therefore the test-then-iterate example is
> fine code.
>
> WDYT?

I’m all in favor of immutable pairs.  However, I expect that a lot of
code out there relies on it.

Moving set-car! and set-cdr! to a different module like in R6 may be a
good first (or second) step.

Thanks,
Ludo’.




  reply	other threads:[~2014-03-02 21:27 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-02 15:55 for-each et al Andy Wingo
2014-03-02 21:27 ` Ludovic Courtès [this message]
2014-03-04 20:30   ` Andy Wingo
2014-03-04 22:35     ` Ludovic Courtès
2014-03-05 19:59       ` Andy Wingo
2014-03-05 22:32         ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87r46ks33b.fsf@gnu.org \
    --to=ludo@gnu.org \
    --cc=guile-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).