From: Chris Riesbeck
Subject: :end default value question
Date: 
Message-ID: <riesbeck-4303DB.16465802032001@news.acns.nwu.edu>
Is there an important reason why the standard says that 
END parameters default to NIL, meaning "length of sequence," 
rather than they default to "length of sequence?"

The RANGE-OF-START-AND-END-PARAMETERS:INTEGER-AND-INTEGER-NIL
discussion in the HyperSpec just says it needed to be
clarified, unless I missed something (not unlikely).

I see why implementations should do it that way,
to avoid calling LENGTH on lists, but would anything
be different for user code had it said END defaults to
length of sequence?

From: Barry Margolin
Subject: Re: :end default value question
Date: 
Message-ID: <nLVn6.55$_47.25461@burlma1-snr2>
In article <······························@news.acns.nwu.edu>,
Chris Riesbeck  <········@ils.nwu.edu> wrote:
>Is there an important reason why the standard says that 
>END parameters default to NIL, meaning "length of sequence," 
>rather than they default to "length of sequence?"
>
>The RANGE-OF-START-AND-END-PARAMETERS:INTEGER-AND-INTEGER-NIL
>discussion in the HyperSpec just says it needed to be
>clarified, unless I missed something (not unlikely).
>
>I see why implementations should do it that way,
>to avoid calling LENGTH on lists, but would anything
>be different for user code had it said END defaults to
>length of sequence?

No.  It's entirely internal to the implementation of the function.  They're
probably described that way in the standard because it was the common way
that these functions were designed in the dialects that CL was based on.
But if an implementor actually made the default be the length of the
sequence, there's probably no way a user could tell.

However, users often write their own function that have interfaces similar
to standard functions.  Describing the standard sequence functions this way
will likely encourage them to do it this way as well.

Note also that no matter what the default is, the function still has to
include something like

  (when (null end)
    (setq end (length sequence)))

within it, to allow the caller to pass NIL explicitly.  So making the
default be (length sequence) means that there will probably be redundant
code: LENGTH will be called in both the default value of the parameter and
in the above construct.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, 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: Kent M Pitman
Subject: Re: :end default value question
Date: 
Message-ID: <sfwzof3rbv2.fsf@world.std.com>
Barry Margolin <······@genuity.net> writes:

> In article <······························@news.acns.nwu.edu>,
> Chris Riesbeck  <········@ils.nwu.edu> wrote:
> >Is there an important reason why the standard says that 
> >END parameters default to NIL, meaning "length of sequence," 
> >rather than they default to "length of sequence?"
> >
> >The RANGE-OF-START-AND-END-PARAMETERS:INTEGER-AND-INTEGER-NIL
> >discussion in the HyperSpec just says it needed to be
> >clarified, unless I missed something (not unlikely).
> >
> >I see why implementations should do it that way,
> >to avoid calling LENGTH on lists, but would anything
> >be different for user code had it said END defaults to
> >length of sequence?

Yes.  By saying it defaults to NIL, you're allowed to pass NIL and have
it mean "please call length for me".  If it defaulted to the number, you
would not be able to assume this service was present.
 
> No.  It's entirely internal to the implementation of the function.

I disagree with Barry here.

> They're
> probably described that way in the standard because it was the common way
> that these functions were designed in the dialects that CL was based on.
> But if an implementor actually made the default be the length of the
> sequence, there's probably no way a user could tell.

:end nil

I use this all the time.

I suspect it's because for safety the function might have to check the length
anyway, and do min of the user-supplied value against the true length.  That
said, if the user does LENGTH, he's potentially doing extra work over just
passing NIL, and slowing things down.  So in the cases where you don't know,
you're better to just pass NIL.  Also, :end nil is textually shorter than
:end <reference-to-the-object>, and in some cases the reference to the object
may not even be a variable access but a function call, as in:
 (search (foo) :start 5 :end nil)
where you'd have to do
 (let ((temp (foo))) (search temp :start 5 :end (length temp)))
in order to call length at all.  Here since SEARCH is going to set up a lambda
variable for the passed value anyway, it's just more convenient.  I also think
there are a host of cases in argument defaulting through cascaded function 
calls where NIL creeps in to mean "i didn't feel like supplying this arg" and
if anything, i'd change things like search to take NIL as a :start to mean 0
just to avoid some of the cases I've sometimes encountered in sloppy code.
But in any case, when I want to write bulletproof optional/key code, I often
do
 (defun foo (&key x y z)
   (unless x (setq x ...))
   (unless y (setq y ...))
   (unless z (setq z ...))
   ...)
rather than
 (defun foo (&key (x ...) (y ...) (z ...))
   ...)
if I have reason to believe the client of the code will be stupid about things
and will mistakenly supply NIL rather than taking the trouble to properly
default things.
From: Barry Margolin
Subject: Re: :end default value question
Date: 
Message-ID: <HiWn6.59$_47.26061@burlma1-snr2>
In article <···············@world.std.com>,
Kent M Pitman  <······@world.std.com> wrote:
>Yes.  By saying it defaults to NIL, you're allowed to pass NIL and have
>it mean "please call length for me".  If it defaulted to the number, you
>would not be able to assume this service was present.

Why not?  The definition of "bounding index designator" already says that
an explicit NIL means "length of sequence".  How the default is described
is irrelevant.

>> No.  It's entirely internal to the implementation of the function.
>
>I disagree with Barry here.
>
>> They're
>> probably described that way in the standard because it was the common way
>> that these functions were designed in the dialects that CL was based on.
>> But if an implementor actually made the default be the length of the
>> sequence, there's probably no way a user could tell.
>
>:end nil
>
>I use this all the time.

So?  You could still do this if the default were (length sequence).

>I suspect it's because for safety the function might have to check the length
>anyway, and do min of the user-supplied value against the true length.  That
>said, if the user does LENGTH, he's potentially doing extra work over just

Who said the user would have to call LENGTH?

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, 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: Kent M Pitman
Subject: Re: :end default value question
Date: 
Message-ID: <sfw66hrhfnl.fsf@world.std.com>
Barry Margolin <······@genuity.net> writes:

> In article <···············@world.std.com>,
> Kent M Pitman  <······@world.std.com> wrote:
> >Yes.  By saying it defaults to NIL, you're allowed to pass NIL and have
> >it mean "please call length for me".  If it defaulted to the number, you
> >would not be able to assume this service was present.
> 
> Why not?  The definition of "bounding index designator" already says that
> an explicit NIL means "length of sequence".  How the default is described
> is irrelevant.

I guess I was (perhaps erroneously) taking the question to have hidden
behind it some question like "could I just default the end argument to nil
so i'd never have that messy non-number in there and I could type-declare
argument to be an integer" and the answer to that is "no".  You have to
at least presume that NIL will sometimes be passed explicitly.  You're right
that the default could be (length string) but that would seem silly since
you have to also do the test yet again later to make sure the default has not
been bypassed by an explicit NIL.  So you're technically not wrong, but I'd
slap the hand of any student who wrote their code to redundantly set the
default in two different places.
From: Barry Margolin
Subject: Re: :end default value question
Date: 
Message-ID: <ZhOo6.7$8q1.19672@burlma1-snr2>
In article <···············@world.std.com>,
Kent M Pitman  <······@world.std.com> wrote:
>Barry Margolin <······@genuity.net> writes:
>
>> In article <···············@world.std.com>,
>> Kent M Pitman  <······@world.std.com> wrote:
>> >Yes.  By saying it defaults to NIL, you're allowed to pass NIL and have
>> >it mean "please call length for me".  If it defaulted to the number, you
>> >would not be able to assume this service was present.
>> 
>> Why not?  The definition of "bounding index designator" already says that
>> an explicit NIL means "length of sequence".  How the default is described
>> is irrelevant.
>
>I guess I was (perhaps erroneously) taking the question to have hidden
>behind it some question like "could I just default the end argument to nil
>so i'd never have that messy non-number in there and I could type-declare
>argument to be an integer" and the answer to that is "no".  

I didn't think he was asking as an implementor, but as a user trying to
understand why the standard was worded as it was.

>							     You have to
>at least presume that NIL will sometimes be passed explicitly.  You're right
>that the default could be (length string) but that would seem silly since
>you have to also do the test yet again later to make sure the default has not
>been bypassed by an explicit NIL.  So you're technically not wrong, but I'd
>slap the hand of any student who wrote their code to redundantly set the
>default in two different places.

I thought I made precisely that point in my post, where I included the code
that's likely to be in the implementation.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, 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: Chris Riesbeck
Subject: Re: :end default value question
Date: 
Message-ID: <riesbeck-01FCA1.12401905032001@news.acns.nwu.edu>
In article <·················@burlma1-snr2>, Barry Margolin 
<······@genuity.net> wrote:

>In article <···············@world.std.com>,
>Kent M Pitman  <······@world.std.com> wrote:
>>Barry Margolin <······@genuity.net> writes:
>>
>>I guess I was (perhaps erroneously) taking the question to have hidden
>>behind it some question like "could I just default the end argument to nil
>>so i'd never have that messy non-number in there and I could type-declare
>>argument to be an integer" and the answer to that is "no".  
>
>I didn't think he was asking as an implementor, but as a user trying to
>understand why the standard was worded as it was.

Correct. I was actually asking as an educator, who constantly
keeps forgetting and telling students :END defaults to length, then
they pull out Steele or Graham, and prove me wrong (again). 

It's a bit more confusing to tell beginners ":END defaults to NIL, 
but NIL means length."
From: Kent M Pitman
Subject: Re: :end default value question
Date: 
Message-ID: <sfwbsrg3s7d.fsf@world.std.com>
Chris Riesbeck <········@ils.nwu.edu> writes:

> It's a bit more confusing to tell beginners ":END defaults to NIL, 
> but NIL means length."

Well, saying ":END defaults to the length" has a hidden lie in it that
NIL is not a possible argument.  I understand that educators do this,
but I also like to think educators get around to eventually saying
the truth.  It seems to me that you need to say somewhere eventually
that NIL *is* a possible argument, or they won't be able to read others'
code or will come to distrust what you say.  If they already know what
it does with NIL, I don't see much difference between:

 ":end defaults to nil."
and
 ":end defaults to the length of the string."

If they don't know what NIL does, and you feel obliged to say, then

 ":end defaults to the length of the string, though you can 
  also pass NIL to mean that."

seems no less concise than

 ":end defaults to nil, which desginates the length of the string."

I guess it's a point of view thing.
From: Barry Margolin
Subject: Re: :end default value question
Date: 
Message-ID: <bcTo6.25$8q1.25308@burlma1-snr2>
In article <···············@world.std.com>,
Kent M Pitman  <······@world.std.com> wrote:
>Chris Riesbeck <········@ils.nwu.edu> writes:
>
>> It's a bit more confusing to tell beginners ":END defaults to NIL, 
>> but NIL means length."
>
>Well, saying ":END defaults to the length" has a hidden lie in it that
>NIL is not a possible argument.

It seems to me that it really depends on how you say it.  If you say
something like "If :END is NIL or not supplied, it goes to the end of the
sequence", you get the entire point across concisely.  The choice of which
to use as the underlying default really only matters to the implementor, to
avoid redundant calls to LENGTH.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, 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: Kent M Pitman
Subject: Re: :end default value question
Date: 
Message-ID: <sfwae6zeuy6.fsf@world.std.com>
Barry Margolin <······@genuity.net> writes:

> In article <···············@world.std.com>,
> Kent M Pitman  <······@world.std.com> wrote:
> >Chris Riesbeck <········@ils.nwu.edu> writes:
> >
> >> It's a bit more confusing to tell beginners ":END defaults to NIL, 
> >> but NIL means length."
> >
> >Well, saying ":END defaults to the length" has a hidden lie in it that
> >NIL is not a possible argument.
> 
> It seems to me that it really depends on how you say it.  If you say
> something like "If :END is NIL or not supplied, it goes to the end of the
> sequence", you get the entire point across concisely.  The choice of which
> to use as the underlying default really only matters to the implementor, to
> avoid redundant calls to LENGTH.

Yes, that's so. As long as in the process you don't end up implying
that defaulting in general occurs for "NIL or unsupplied" and the user
is cued to understand that this function is special in its treatment
of that one parameter.  For example, :start is not similarly
defaulted.  I think it's easier, cleaner, and more consistent to
explain that it's NIL because that's the stretchy end of the array and
it's useful to have a designator for that than it is to make it look
like the defaulting behavior is irregularly applied, which it is not.
Maybe you think that's splitting hairs, or just to fine a point to be
bothered with, but I don't.  Oh well.  This is why there is no end to
textbooks, I guess.