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: [PATCH] Avoid `SCM_VALIDATE_LIST ()'
Date: Mon, 01 Sep 2008 23:47:34 +0200	[thread overview]
Message-ID: <87bpz7h72h.fsf@gnu.org> (raw)
In-Reply-To: 49dd78620809011409w8902d24q5734da921d6dfbff@mail.gmail.com

Hi Neil,

"Neil Jerram" <neiljerram@googlemail.com> writes:

>> so that they
>> don't validate their input with `SCM_VALIDATE_LIST ()' since it's O(n).
>
> I'm afraid I don't get your rationale, because all these functions are
> O(n) anyway.

You're right, but it's always better to traverse the list once rather
than twice.  :-)

It doesn't feel right to impose that overhead "just" for the sake of
type-checking.

Type-checking using `list?' in these cases was actually overzealous
since neither RnRS nor SRFI-1 require it.

Note: We could change these functions to still diagnose what `list?'
diagnoses while avoiding `SCM_VALIDATE_LIST ()' such that only one list
traversal is done.  It boils down to implementing the tortoise and the
hare in each function, as shown in the `list-copy' patch.

> Did you find the use of SCM_VALIDATE_LIST () causing a problem in real
> practical code?

What does that mean?  Real practical code using `memq' behaves just as
if it called `memq' twice, that's it.  Whether that is a "problem"
depends on how often that happens, how long the list is, and how long
you're willing to wait.  :-)

>> A side-effect (besides performance improvements) is that all these
>> functions will now happily traverse circular lists, and will silently
>> deal with dotted lists.  This is acceptable behavior IMO.
>
> Are you sure about traversing circular lists?  From my reading of your
> patch, I would expect:
>
> (memq 'not-in-the-list some-circular-list)
> =>
> (don't know, still waiting...)

Yes, that's what I meant by "happily traverse circular lists".  :-)

> What do reverse* do on a circular list?  What do concatenate* do?

They keep reversing or concatenating---and it takes long!  :-)

> There are a few more specific comments below, but on balance, at the
> moment, I'm seeing more disadvantages here than benefit...

Again, if the disadvantage is that circular lists are not diagnosed, we
can add tortoise-and-hare protection to each function while still
avoiding double traversal.  I'm not sure it's worth it, though.

>> +** Remove argument type checking with `list?' in some list-related functions
>
> It's easy to read that as just "Remove argument type checking".  Could
> we say "Improve scalability of some list-related functions" instead,
> and leave the type checking detail to the following para?

Right.

>> @@ -367,15 +367,19 @@ SCM_DEFINE (scm_reverse_x, "reverse!", 1, 1, 0,
>>  	    "@code{reverse!}")
>>  #define FUNC_NAME s_scm_reverse_x
>>  {
>> -  SCM_VALIDATE_LIST (1, lst);
>>    if (SCM_UNBNDP (new_tail))
>>      new_tail = SCM_EOL;
>>    else
>> -    SCM_VALIDATE_LIST (2, new_tail);
>> +    SCM_ASSERT (scm_is_pair (new_tail) || SCM_NULL_OR_NIL_P (new_tail),
>> +		new_tail, 2, FUNC_NAME);
>
> Why does new_tail need to satisfy this condition?  Please either add a
> comment to explain, or just remove.

It's a mechanical change: the code used to check for a proper list, I
just changed it to check for a list (i.e., '() or a pair).

> Note that if SCM_VALIDATE_CONS fails half way through the "list", the
> input list will have been destructively modified such that it is
> neither the same as when it started, nor a complete reversed list.  Is
> that a concern?

(I think that was `reverse!'.)

Portable RnRS code and code written without looking at `list.c' must use
`list?' before calling `reverse!' to protect from such situations.  So,
to me, that's not a concern.

Now, one could argue that there's code out there that relies on Guile's
undocumented over-restriction on input arguments.  That's always
possible, but hopefully sufficiently rare.

>> @@ -546,7 +550,8 @@ SCM_DEFINE (scm_list_copy, "list-copy", 1, 0, 0,
>>    SCM * fill_here;
>>    SCM from_here;
>>
>> -  SCM_VALIDATE_LIST (1, lst);
>> +  SCM_ASSERT (scm_is_pair (lst) || SCM_NULL_OR_NIL_P (lst),
>> +	      lst, 1, FUNC_NAME);
>
> Why impose this condition specifically on the head of the provided
> list?

So that "(list-copy 1)" raises an exception, rather than being silently
ignored (as is the case with `list-copy' from `srfi-1.c').  Again, a
mechanical change.

Thanks,
Ludo'.





  reply	other threads:[~2008-09-01 21:47 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-31 22:02 [PATCH] Avoid `SCM_VALIDATE_LIST ()' Ludovic Courtès
2008-09-01  0:12 ` Han-Wen Nienhuys
2008-09-01 20:19   ` Neil Jerram
2008-09-01 20:30   ` Ludovic Courtès
2008-09-02  2:40     ` Han-Wen Nienhuys
2008-09-06 22:23       ` Neil Jerram
2008-09-06 21:36     ` Neil Jerram
2008-09-07  4:23     ` Ken Raeburn
2008-09-07 15:24       ` Neil Jerram
2008-09-07 17:30         ` Ken Raeburn
2008-09-07 19:21           ` Neil Jerram
2008-09-08 23:11         ` Neil Jerram
2008-09-09  8:28           ` Ludovic Courtès
2008-09-10 20:43             ` Neil Jerram
2008-09-04 18:24   ` Andy Wingo
2008-09-05  0:10     ` Han-Wen Nienhuys
2008-09-05  1:06       ` Andy Wingo
2008-09-06 22:45         ` Neil Jerram
2008-09-07  2:33           ` Han-Wen Nienhuys
2008-09-07 13:38             ` Neil Jerram
2008-09-07 15:00               ` Han-Wen Nienhuys
2008-09-07 16:19                 ` Neil Jerram
2008-09-07 19:25                   ` Han-Wen Nienhuys
2008-09-07 14:05             ` Andy Wingo
2008-09-07 15:38               ` development goals (was: [PATCH] Avoid `SCM_VALIDATE_LIST ()') Han-Wen Nienhuys
2008-09-07 20:03                 ` Neil Jerram
2008-09-08  4:28                   ` development goals Han-Wen Nienhuys
2008-09-08 10:16                     ` Ludovic Courtès
2008-09-08 13:57                       ` Han-Wen Nienhuys
2008-09-09  7:08                       ` Andy Wingo
2008-09-08 10:27                   ` Ludovic Courtès
2008-09-06 22:40     ` [PATCH] Avoid `SCM_VALIDATE_LIST ()' Neil Jerram
2008-09-01 21:09 ` Neil Jerram
2008-09-01 21:47   ` Ludovic Courtès [this message]
2008-09-06 22:15     ` Neil Jerram
2008-09-08  9:40       ` Ludovic Courtès
2008-09-06 23:11     ` Mikael Djurfeldt
2008-09-07  2:43       ` Han-Wen Nienhuys
2008-09-07 15:04         ` Neil Jerram
2008-09-07 13:32       ` Neil Jerram
2008-09-02  2:44   ` Han-Wen Nienhuys
2008-09-06 22:32     ` Neil Jerram
2008-09-08  3:13       ` Han-Wen Nienhuys
2008-09-08  4:42         ` Clinton Ebadi
2008-09-08  9:47           ` 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=87bpz7h72h.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).