From: David Bakhash
Subject: #'length being generic
Date: 
Message-ID: <wk1zl5q1dk.fsf@mit.edu>
Question:

Since the function #'length takes any type of sequence, and since it
would be so nice and handy to be able to use "length" as the name of
many other functions in our own code, why didn't they just decide to
make #'length generic?  That way, they could also have used it for
things like hashtables instead of #'hash-table-size, etc.

dave

From: Jeffrey Mark Siskind
Subject: Re: #'length being generic
Date: 
Message-ID: <yq7pv8pvipz.fsf@qobi.nj.nec.com>
> Question:
> 
> Since the function #'length takes any type of sequence, and since it
> would be so nice and handy to be able to use "length" as the name of
> many other functions in our own code, why didn't they just decide to
> make #'length generic?  That way, they could also have used it for
> things like hashtables instead of #'hash-table-size, etc.

Answer: history

Joke: How was God able to create the whole world in only six days?
      He didn't have an installed base.

    Jeff (http://www.neci.nj.nec.com/homepages/qobi)
From: Lyman S. Taylor
Subject: Re: #'length being generic
Date: 
Message-ID: <775fsu$j92@pravda.cc.gatech.edu>
In article <··············@mit.edu>, David Bakhash  <·····@mit.edu> wrote:
>Question:
>
>Since the function #'length takes any type of sequence, and since it
>would be so nice and handy to be able to use "length" as the name of
>many other functions in our own code, why didn't they just decide to
>make #'length generic? 

Two factors to consider. 

   Legacy....
   Becuase  LENGTH very likely predates the wide spread OO revolution.
   In the present context, why on earth would use the words CAR  and CDR to
   get at the two portions of a cons cell?  I think they are better names. 
   Being an "old" language means that some names may have been 
   "misappropriated".   There is no way to "fix" that and maintain 
    compatibility with the legacy code.

   Dispatch...
   Because you don't need an optimized method dispatch compiler
   to not take a speed hit.  If you know what all the types a 
   "generic"/polymorphic function will take you might write a highly optimized 
   function by hand and/or play tricks with the compiler if you have enough
   type info.  [ e.g., 

      (defun length ( ... )
             (typecase ...
                ( type1 ...  (type1-length .. ))
                ( type2 ...  (type2-length .. )))
                 .... ))
    if  inlined and the type know could result in a direct call to the 
    specific function being invoked/inlined.   Doing the same for 
    multimethod dispatch is a tad bit more tricky. ]









-- 
					
Lyman S. Taylor                "Twinkie Cream; food of the Gods" 
(·····@cc.gatech.edu)                     Jarod, "The Pretender" 
From: Barry Margolin
Subject: Re: #'length being generic
Date: 
Message-ID: <iOrl2.92$z15.5037@burlma1-snr1.gtei.net>
In article <··············@mit.edu>, David Bakhash  <·····@mit.edu> wrote:
>Question:
>
>Since the function #'length takes any type of sequence, and since it
>would be so nice and handy to be able to use "length" as the name of
>many other functions in our own code, why didn't they just decide to
>make #'length generic?  That way, they could also have used it for
>things like hashtables instead of #'hash-table-size, etc.

Compatibility, mostly.  For the most part, CLOS can be treated as an add-on
to the language, and that's how it was put into most implementations.
During the X3J13 process, CLOS was a pretty late addition (we knew from the
start that we would be adding an object system, but the specifics all had
to be designed).  Except for some very high level features like PRINT and
DESCRIBE, we didn't make the rest of the language dependent on CLOS.  Even
the condition system, which contains a type hierarchy of its own, is not
required to use CLOS to implement those types.

This approach also makes it easier to bootstrap CLOS.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
From: ········@poboxes.com
Subject: Re: #'length being generic
Date: 
Message-ID: <777fc2$4c5$1@nnrp1.dejanews.com>
(This is a continuation of my previous posting.)

There is more to making functions such as LENGTH generic and
letting users add methods to them.  (I had been enlightened
about it but had forgotten.)

If two different modules each define a method for LENGTH for
the same class (but doing different things), and if those
modules get loaded together, one loses.

Maybe it would be nice if we had an object system where each
module might have its own environment of methods.  In that
way the effective method would be computed as a combination
of (A) global methods and (B) methods belonging only to the
module that calls the generic functions.  (This is a very
rough sketch---I don't claim it can be given a clear meaning.)

With what we have now, one could call the generic function
(LENGTH, whatever) via a hook, and each module could have
this hook bound to its own generic function if needed.
(PROGV might be useful here to establish an appropriate
dynamic environment.)  This appropach is far from perfect,
of course, as it makes it hard to share methods between
the modules, and as (FUNCALL *FOO* ...) is not necessarily
fast.

I wonder if one could play with (one of) the MOP(s) to have
one generic function inherit methods from another:

  G1 inherits from G0 when, roughly, G1 does not have a
  method for a class and when G1 is called on an object
  of that class, G0's method for that class is used for
  the effective method.

(Again, there is a lot to do to refine this definition, but
the main question is whether that makes sense at all and is
really needed.)

Have a nice day or night,
Vassil.


-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Barry Margolin
Subject: Re: #'length being generic
Date: 
Message-ID: <D1Wl2.11$oD6.311@burlma1-snr1.gtei.net>
In article <············@nnrp1.dejanews.com>,  <········@poboxes.com> wrote:
>If two different modules each define a method for LENGTH for
>the same class (but doing different things), and if those
>modules get loaded together, one loses.

This is why users are not allowed to define methods for generic functions
in the COMMON-LISP package when all the specializers are classes in the
COMMON-LISP package.

>Maybe it would be nice if we had an object system where each
>module might have its own environment of methods.  

First we would have to add a module system to CL.

>With what we have now, one could call the generic function
>(LENGTH, whatever) via a hook, and each module could have
>this hook bound to its own generic function if needed.
>(PROGV might be useful here to establish an appropriate
>dynamic environment.)  This appropach is far from perfect,
>of course, as it makes it hard to share methods between
>the modules, and as (FUNCALL *FOO* ...) is not necessarily
>fast.

If you want a generic function for your application, why does it have to be
named LENGTH?  Just pick your own name, in your own package, and then there
won't be any conflict.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
From: Kent M Pitman
Subject: Re: #'length being generic
Date: 
Message-ID: <sfw1zl3fxhl.fsf@world.std.com>
The real reason LENGTH is sealed (i.e., can't be extended by
DEFMETHOD) is that generics were new at the time we were making CLTL1
and we worried that allowing DEFMETHOD would lead to rampant
overloading and a big mess.

There is more to defining a generic than allowing method definition.
You also have to describe the generic such that people can tell the
difference between a method that properly extends the behavior and
a method that merely overloads the behavior.  Regardless of what
others might take overloading to mean, I use the term myself to refer
to the thing people so often do to "+" in some languages so that
"foo" + "bar" => "foobar".  That's an example of the mess that results
if you give people a little rope.

I consider it a rule of good design that you should not make available
a generic for method writing unless you can say in English (or some
suitable substitute natural language) what the operation does.  No one
ever did this for CL, so CL never became more generic.

Before you think it's utterly trivial, consider that NIL (the New
Implementation of Lisp for the VAX done in the late 1970's and early
1980's and feeding into the CL design) had a bug in its original
definition of LENGTH which made various people cautious about whether
there were lurking problems we should study more before doing things
like were suggested here.  Consider:

 (LENGTH '(A B . "cde")) => 5

was the definition that NIL had because it had definitions something
like:

 (DEFMETHOD LENGTH ((X CONS)) (+ 1 (LENGTH (CDR X))))

If you think about it, the bug here is not a simple "impementation
error" but is related to the whole issue of "intentional type" that
I keep talking about in the discussion of what makes a good EQUAL.
Yes, one can fix things for LENGTH by just defining what it will
assume, but if you make LENGTH fully generic, then what if I do want
to talk about the length of a tree, where tree is a layered type
on CONS, which already has a definition.  Or LENGTH of a multi-d array.

It's easy enough to shadow LENGTH and make the new one generic if
you want that behavior.  And that's exactly what the designers
explicitly decided about LENGTH and a heap of other functions when
we decided they would not be generic functions.  It was discussed.
And we decided "later" was the right thing.  Maybe now is indeed
"later", of course.  I didn't mean it's a closed issue forever.
But I'm just saying we weren't as clueless as it might seem.
From: David Bakhash
Subject: Re: #'length being generic
Date: 
Message-ID: <wksodjntv8.fsf@mit.edu>
Kent M Pitman <······@world.std.com> writes:

> It's easy enough to shadow LENGTH and make the new one generic if
> you want that behavior.  And that's exactly what the designers
> explicitly decided about LENGTH and a heap of other functions when
> we decided they would not be generic functions.  It was discussed.
> And we decided "later" was the right thing.  Maybe now is indeed
> "later", of course.  I didn't mean it's a closed issue forever.
> But I'm just saying we weren't as clueless as it might seem.

Yes.  This is a more-than-sufficient explaination, and now I
understand.

I'm glad that there are people out there willing to explain the history
here.  It makes sense, and now, come to think of it, #'length not being
generic has never hurt me; I just do what Barry said (use another
name).  Originally, I'd thought that since there were so many primitive
Lisp data structures which have a "length" concept, it would make sense
that that be generic.  But with the bootstrapping issue of
CLOS/non-CLOS, and what Kent mentions, it makes a lot of sense.
#'lenght should not be weighed down by CLOS.

dave
From: Tim Bradshaw
Subject: Re: #'length being generic
Date: 
Message-ID: <ey367ac6yih.fsf@todday.aiai.ed.ac.uk>
* Kent M Pitman wrote:
> There is more to defining a generic than allowing method definition.
> You also have to describe the generic such that people can tell the
> difference between a method that properly extends the behavior and
> a method that merely overloads the behavior.  Regardless of what
> others might take overloading to mean, I use the term myself to refer
> to the thing people so often do to "+" in some languages so that
> "foo" + "bar" => "foobar".  That's an example of the mess that results
> if you give people a little rope.

I think an even better example is the thing that made me feel pretty
queasy about C++ when I first came across it in the 80s: almost the
first thing you come across is that it *standardly* overloads the
bit-shift operators (<< and >>) to do I/O!

--tim
From: ········@poboxes.com
Subject: Re: #'length being generic
Date: 
Message-ID: <77hrpb$bog$1@nnrp1.dejanews.com>
In article <···············@todday.aiai.ed.ac.uk>,
  Tim Bradshaw <···@aiai.ed.ac.uk> wrote:
> * Kent M Pitman wrote:
(...)
> > to the thing people so often do to "+" in some languages so that
> > "foo" + "bar" => "foobar".  That's an example of the mess that results
> > if you give people a little rope.
>
> I think an even better example is the thing that made me feel pretty
> queasy about C++ when I first came across it in the 80s: almost the
> first thing you come across is that it *standardly* overloads the
> bit-shift operators (<< and >>) to do I/O!

Part of the reason for that is that languages such as C++
(and Ada,^1 for that matter) are broken in not allowing the user
to define new tokens for operators.^2  Even if I want to use
(say) "->" and "<-" for I/O, I can't, and have to pick up
that one from among the predefined tokens that looks the best
approximation.
______________
^1 I don't know about the latest developments.
^2 Yes I know there are good reasons for that but I think
the reasons why this capability should be in a decent language
with polymorphism are even better---and it is not impossible.

With "foo" + "bar" it is a little different because to many
people string concatenation _is_ a kind of addition (to others
it is a kind of multiplication, so they might pronounce `foo foo'
as `foo squared'...).

Have a nice day or night,
Vassil.

Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: ········@poboxes.com
Subject: Re: #'length being generic
Date: 
Message-ID: <77b0pu$uhu$1@nnrp1.dejanews.com>
In article <················@burlma1-snr1.gtei.net>,
  Barry Margolin <······@bbnplanet.com> wrote:
> In article <············@nnrp1.dejanews.com>,  <········@poboxes.com> wrote:
(...)

> >Maybe it would be nice if we had an object system where each
> >module might have its own environment of methods.
>
> First we would have to add a module system to CL.

Of course.  I was just mentioning one thing from my own wish
list for a CL module system.


> >With what we have now, one could call the generic function
> >(LENGTH, whatever) via a hook, and each module could have
> >this hook bound to its own generic function if needed.
> >(PROGV might be useful here to establish an appropriate
> >dynamic environment.)  This appropach is far from perfect,
> >of course, as it makes it hard to share methods between
> >the modules, and as (FUNCALL *FOO* ...) is not necessarily
> >fast.
>
> If you want a generic function for your application, why does it have to be
> named LENGTH?  Just pick your own name, in your own package, and then there
> won't be any conflict.

Again, I was just thinking aloud what could be done in the
case of a `multi-user' (or `multi-application') generic function,
if it is a good idea to have one at all.

Have a nice day or night,
Vassil.

Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: ········@poboxes.com
Subject: Re: #'length being generic
Date: 
Message-ID: <775nvv$ljj$1@nnrp1.dejanews.com>
In article <··············@mit.edu>,
  David Bakhash <·····@mit.edu> wrote:
> Question:
>
> Since the function #'length takes any type of sequence, and since it
> would be so nice and handy to be able to use "length" as the name of
> many other functions in our own code, why didn't they just decide to
> make #'length generic?  That way, they could also have used it for
> things like hashtables instead of #'hash-table-size, etc.

I have thought of (but never had the time) defining a package
called, say, GENERIC (nickname G) which would `mirror in a
generic way' non-generic functions from the CL package.  Then
one would be able to call e.g. G:LENGTH, or (for the brave)
do shadowing imports.

Obviously the methods for G:LENGTH on vectors and lists would
call CL:LENGTH and would supply declarations that good compilers
can utilise.

The zeroeth step would be coming up with a specification of the
functions in the G package so that if people start implementing
them (a big if I know), we would not come up with incompatible
interfaces to basically the same functions.

Good luck,
Vassil.

Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own