From: Joe Marshall on
"Tron3k" <tron3k(a)gmail.com> writes:

> Kent M Pitman wrote:
>> Now think about
>> (length '(a b . "foo"))
>
> Intriguing possibility: Is it necessarily the wrong thing for that to
> return 5? Maybe it should do just that, while a more specific function
> LIST-LENGTH would throw an error.

Supposing you have a variable *FOO*. You call

(length *foo*)
=> 5

Should (elt *foo* 4) give you an error? What should it return if
*foo* is '(a b . "foo")? Could you SETF it?

What should (length (concatenate 'list *foo* *foo*)) return?

--
~jrm
From: Kent M Pitman on
"Tron3k" <tron3k(a)gmail.com> writes:

> Kent M Pitman wrote:
> > Now think about
> > (length '(a b . "foo"))
>
> Intriguing possibility: Is it necessarily the wrong thing for that to
> return 5? Maybe it should do just that, while a more specific function
> LIST-LENGTH would throw an error.

Necessarily? No.

Likely? Yes.

While you can think up uses for it, there are also already tons of non-uses
(that is, errors wanting to be caught). Making those things "work" is the
same as not detecting those errors.

It's so easy to write an operator that does what you suggest you might
in this case that one question is why you would want to perturb
others' existing code by an incompatible definition ...

But the main point is that whether this is right is a matter of "intention"
and any assertion that this is something that is dynamically knowable is
improper. As such, the decision is intrinsically arbitrary, and favoring
compabitility in the arbitrary seems a good plan to me...
See http://www.nhplace.com/kent/PS/EQUAL.html for more exposition on this.


From: Kent M Pitman on
Joe Marshall <prunesquallor(a)comcast.net> writes:

> "Tron3k" <tron3k(a)gmail.com> writes:
>
> > Kent M Pitman wrote:
> >> Now think about
> >> (length '(a b . "foo"))
> >
> > Intriguing possibility: Is it necessarily the wrong thing for that to
> > return 5? Maybe it should do just that, while a more specific function
> > LIST-LENGTH would throw an error.
>
> Supposing you have a variable *FOO*. You call
>
> (length *foo*)
> => 5
>
> Should (elt *foo* 4) give you an error? What should it return if
> *foo* is '(a b . "foo")? Could you SETF it?
>
> What should (length (concatenate 'list *foo* *foo*)) return?

One person's intrigue is another's catastrophe. You seem to
implicitly suggest that no one is relying on getting an error message
here and that the change you propose is compatible. Or else that the
compatibility concern is of no consequence. See
http://www.nhplace.com/kent/CL/x3j13-86-020.html
for historical context.

And what should (concatenate 'list *foo* *foo*) return, for that matter.
Just because you expect an output list doesn't mean you mean to treat
the inputs as lists... CL defines their type to be dynamically inspectable.

One reason ELT is interesting is that it's already inefficient for ELT to
worry someone will use it to write some algorithm that supposes random access.
At least now ELT can sniff at the type it's given and select an appropriate
algorithm for doing its work based on that type. If the type can vary
recursively, you take away even that minimal class of dynamic optimization.

Remember that one reason we signal errors about non-homogeneity of type
is to permit programs that assume a local degree of homogeneity at least
in the container structure. This, at least, is the motivation for ENDP.
ENDP makes very little remaining sense in a world where the type of the
object changes as you recurse, since it's all about the intention of it
not changing.

Questions like this affect the whole fabric of the language if you not only
make a random local change but start propagating its implications into
changes around it. That fact--of destabilization of time-tested sets of
operations--is why we didn't originally do the change to generic, and it's
why I stand by that now.

I don't have opposition to a new generic set of operations being written
as a library for those who like that kind of thing. It's easy enough to do.
I don't say languages written with this as a basic premise will fail.
I just say that at some point if you morph the core of CL more than a certain
amount to suit a new community, you sacrifice the original community for
which it is built, most of whom are not clamoring for this change in order
to get their work done.

Build the experiment first. Find out if people use it exclusively and
abandon the old ways. THEN argue that the old unused operators should
fall away and yield their names to the new.

Then again, since you can build a whole new TRON3K-COMMON-LISP package and
seed it with whatever you want without changing CL at all, I'm STILL not sure
why you would sacrifice the ability to cross-call old code without modification
and not just teach people to start compatibly in TRON3K-COMMON-LISP...
From: M Jared Finder on
Kent M Pitman wrote:
> "Tron3k" <tron3k(a)gmail.com> writes:
>>Kent M Pitman wrote:
>>
>>>Now think about
>>> (length '(a b . "foo"))
>>
>>Intriguing possibility: Is it necessarily the wrong thing for that to
>>return 5? Maybe it should do just that, while a more specific function
>>LIST-LENGTH would throw an error.
>
> Necessarily? No.
>
> Likely? Yes.
>
> While you can think up uses for it, there are also already tons of non-uses
> (that is, errors wanting to be caught). Making those things "work" is the
> same as not detecting those errors.

I agree with this, but I do not see how that makes genericizing the
sequence functions any more difficult. Require LENGTH to be passed a
sequence, and not an improper list. If passed an improper list, length
should raise a condition of type type-error, just like it does now.

This disallows the "clever" implementation of length for lists that you
listed:

> (defmethod length ((x cons)) (+ 1 (length (cdr x))))
> (defmethod length ((x null)) 0)

So don't implement it that way!

-- MJF
From: Paul F. Dietz on
M Jared Finder wrote:

> This disallows the "clever" implementation of length for lists that you
> listed:
>
>> (defmethod length ((x cons)) (+ 1 (length (cdr x))))
>> (defmethod length ((x null)) 0)
>
>
> So don't implement it that way!

The reason I would like to see functions like LENGTH implemented
as generic functions is not so that this clever (but wrong,
as Kent points out) implementation could be used, but so that
users could add their own sequence types (and, elsewhere, their
own streams, and hash tables, and so on).

Paul
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9
Prev: Lisp and Web Programming
Next: Koch figures