From: Joel Reymont
Subject: Overloading in Lisp
Date: 
Message-ID: <1123184359.232326.9870@o13g2000cwo.googlegroups.com>
Folks,

Say I'm looking to overload + or * to sum or multiple fixnums and
floats, or vectors of fixnums and floats. This is a trivial example but
I might want to have specialized versions of the different argument
permutatios (fixnum + fixnum, fixnum + float, float + float) for
efficiency.

How would I do this with Lisp?

The folks at ITA Software seem to imply in this article
http://www.paulgraham.com/carl.html that using generics is bad for
performance.

    Thanks, Joel

From: Joe Marshall
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <psstqxp6.fsf@ccs.neu.edu>
"Joel Reymont" <······@gmail.com> writes:

> The folks at ITA Software seem to imply in this article
> http://www.paulgraham.com/carl.html that using generics is bad for
> performance.

They aren't bad, but they do a lot more work than you might want if
you have prior knowledge of the argument types.
From: Kent M Pitman
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <ufytpjxcm.fsf@nhplace.com>
"Joel Reymont" <······@gmail.com> writes:

> Folks,
> 
> Say I'm looking to overload + or * to sum or multiple fixnums and
> floats, or vectors of fixnums and floats. This is a trivial example but
> I might want to have specialized versions of the different argument
> permutatios (fixnum + fixnum, fixnum + float, float + float) for
> efficiency.
> 
> How would I do this with Lisp?

Use package separation, shadow * and +, make them generic.
Leave the standard ones alone.

Don't talk about overloading.  Generics work for you here, and you
should use them.  I use the term overloading for something that is
unrelated being shoehorned into the same name, like string concatenation
on plus.  At least you can make a case that vectors will operate
properly under +, *, etc in a way that concatenation largely will not.

> The folks at ITA Software seem to imply in this article
> http://www.paulgraham.com/carl.html that using generics is bad for
> performance.

You could try using generics with compiler macros that expand your
generics into regular function calls that the compiler can optimize
when the args are of known types.

Because CL doesn't give you access to type information, it may be
tricky to write such macros though.  But there's nothing wrong with
asking vendors how much of the CLTL2 support for environment
manipulation they have.  That stuff didn't end up in ANSI CL for
various design reasons but not because the system was bankrupt, just
because it wasn't final/bug-free enough to freeze.  It should be finished
and a community consensus should be evolved.
From: Joel Reymont
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <1123185799.069056.160680@o13g2000cwo.googlegroups.com>
Kent, Paolo,

Would you kindly give me an example of how I would implement generics
with compiler macros for + or * or whatever?

Do I use typecase to expand the generics?

I do not completely understand generics at this point and how I can
apply them to this problem. All I understand is that defmethod is a
simpler version of defgeneric :-).

    Thanks, Joel
From: Paolo Amoroso
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <877jf1savq.fsf@plato.moon.paoloamoroso.it>
"Joel Reymont" <······@gmail.com> writes:

> Kent, Paolo,
>
> Would you kindly give me an example of how I would implement generics
> with compiler macros for + or * or whatever?
>
> Do I use typecase to expand the generics?
>
> I do not completely understand generics at this point and how I can
> apply them to this problem. All I understand is that defmethod is a
> simpler version of defgeneric :-).
>
>     Thanks, Joel
>

I'm afraid all I can do is mention some tutorial material on compiler
macros (see section `Ernst's Lecture: "Macros and General Code Walkers
in Lisp - how useful! or, how useful?"'):

  http://lisp.tech.coop/lisp-user-meeting-amsterdam-april-2004


Paolo
-- 
Why Lisp? http://lisp.tech.coop/RtL%20Highlight%20Film
Recommended Common Lisp libraries/tools:
- ASDF/ASDF-INSTALL: system building/installation
- CL-PPCRE: regular expressions
- UFFI: Foreign Function Interface
From: Pascal Bourguignon
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <87vf2lxwja.fsf@thalassa.informatimago.com>
"Joel Reymont" <······@gmail.com> writes:

> Kent, Paolo,
>
> Would you kindly give me an example of how I would implement generics
> with compiler macros for + or * or whatever?
>
> Do I use typecase to expand the generics?
>
> I do not completely understand generics at this point and how I can
> apply them to this problem. All I understand is that defmethod is a
> simpler version of defgeneric :-).

(defpackage "V"
  (:use "COMMON-LISP")
  (:shadow "+" "*"))

(defgeneric + (arg &rest args))
(defgeneric * (arg &rest args))

(defun v+ (&rest vectors) (apply (function map) 'vector (function cl:+) vectors))
(defun v* (&rest vectors) (apply (function map) 'vector (function cl:*) vectors))

(defmethod + ((arg number) &rest args) (apply (function cl:+) arg args))
(defmethod + ((arg vector) &rest args) (apply (function v+)   arg args))

(defmethod * ((arg number) &rest args) (apply (function cl:*) arg args))
(defmethod * ((arg vector) &rest args) (apply (function v*)   arg args))

(define-compiler-macro + (&whole form arg &rest args)
  (cond
    ((some (function numberp) (cons arg args))  `(cl:+ arg ,@args))
    ((some (function vectorp) (cons arg args))  `(v+   arg ,@args))
    (t form)))

(define-compiler-macro * (&whole form arg &rest args)
  (cond
    ((some (function numberp) (cons arg args))  `(cl:* arg ,@args))
    ((some (function vectorp) (cons arg args))  `(v*   arg ,@args))
    (t form)))

(do-external-symbols (sym "COMMON-LISP")
  (export (intern (symbol-name sym))))


But these simple compiler macros ean you little, since they work only
when at least one argument is a literal.  You'd need to implement a
full type inference to detect things like:

   (let ((a (get-a-vec)) (b (get-a-vec))) (+ a b))

and generate:

   (let ((a (get-a-vec)) (b (get-a-vec))) (v+ a b))



More over, + and * can take 0 argument and return the neutral element:
(+) --> 0
(*) --> 1

so you'd have to write:

(defgeneric + (&rest args))
(defgeneric * (&rest args))

and then the generic function cannot dispatch.  So it's better to
forget generic functions and do it yourself:


(defun + (&rest args)
  (cond ((null args)   (cl:+))
        ((vectorp arg) (apply (function v+)   arg args))
        (t             (apply (function cl:+) arg args))))


(defun * (&rest args)
  (cond ((null args)   (cl:*))
        ((vectorp arg) (apply (function v*)   arg args))
        (t             (apply (function cl:*) arg args))))

You can still write compiler macros.


Finally, note that there are several products:

 scalar * vector --> vector     (* 2 #(1 2 3))          --> #(2 4 6)
 vector � vector --> scalar     (� #(1/2 0 1) #(2 4 6)) --> 7
 vector � vector --> vector     (� #(1/2 0 1) #(2 4 6)) --> #(-4 -3 2)
 etc

Perhaps you won't want to "overload" * so much...


-- 
"You question the worthiness of my code? I should kill you where you
stand!"
From: Joel Reymont
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <1123189641.878820.90440@g47g2000cwa.googlegroups.com>
Thanks Pascal! I don' think I would have figured that out myself.

This type of "overloading" is apparently quite easy to do in Haskell or
OCaml. I'm not dying to use them, though.

Also, forgive me for being stupid but where does arg come from in the
example below:

>(defun * (&rest args)
>  (cond ((null args)   (cl:*))
>        ((vectorp arg) (apply (function v*)   arg args))
>        (t             (apply (function cl:*) arg args))))

Should it be (defun * (arg &rest args) ...) instead?

    Thanks, Joel
From: Pascal Bourguignon
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <87r7d9xnpw.fsf@thalassa.informatimago.com>
"Joel Reymont" <······@gmail.com> writes:

> Thanks Pascal! I don' think I would have figured that out myself.
>
> This type of "overloading" is apparently quite easy to do in Haskell or
> OCaml. I'm not dying to use them, though.
>
> Also, forgive me for being stupid but where does arg come from in the
> example below:
>
>>(defun * (&rest args)
>>  (cond ((null args)   (cl:*))
>>        ((vectorp arg) (apply (function v*)   arg args))
>>        (t             (apply (function cl:*) arg args))))
>
> Should it be (defun * (arg &rest args) ...) instead?

(cl:*) --> 1

(defun * (arg &rest args) ...) 
(*) --> error

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
You never feed me.
Perhaps I'll sleep on your face.
That will sure show you.
From: Edi Weitz
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <uoe8d45f5.fsf@agharta.de>
On Fri, 05 Aug 2005 01:54:19 +0200, Pascal Bourguignon <····@mouse-potato.com> wrote:

> "Joel Reymont" <······@gmail.com> writes:
>
>> Also, forgive me for being stupid but where does arg come from in
>> the example below:
>>
>>>(defun * (&rest args)
>>>  (cond ((null args)   (cl:*))
>>>        ((vectorp arg) (apply (function v*)   arg args))
>>>        (t             (apply (function cl:*) arg args))))
>>
>> Should it be (defun * (arg &rest args) ...) instead?
>
> (cl:*) --> 1
>
> (defun * (arg &rest args) ...) 
> (*) --> error

That still doesn't explain where the ARG comes from in your
definition.  Something like this is more likely to work:

  (defun * (&rest args)
    (cond ((null args) 1)
          ((vectorp (first args)) (apply #'v* args))
          (t (apply #'cl:* args))))

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Pascal Bourguignon
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <87mznxxclg.fsf@thalassa.informatimago.com>
Edi Weitz <········@agharta.de> writes:

> On Fri, 05 Aug 2005 01:54:19 +0200, Pascal Bourguignon <····@mouse-potato.com> wrote:
>
>> "Joel Reymont" <······@gmail.com> writes:
>>
>>> Also, forgive me for being stupid but where does arg come from in
>>> the example below:
>>>
>>>>(defun * (&rest args)
>>>>  (cond ((null args)   (cl:*))
>>>>        ((vectorp arg) (apply (function v*)   arg args))
>>>>        (t             (apply (function cl:*) arg args))))
>>>
>>> Should it be (defun * (arg &rest args) ...) instead?
>>
>> (cl:*) --> 1
>>
>> (defun * (arg &rest args) ...) 
>> (*) --> error
>
> That still doesn't explain where the ARG comes from in your
> definition.  Something like this is more likely to work:
>
>   (defun * (&rest args)
>     (cond ((null args) 1)
>           ((vectorp (first args)) (apply #'v* args))
>           (t (apply #'cl:* args))))

Read the thread.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
I need a new toy.
Tail of black dog keeps good time.
Pounce! Good dog! Good dog!
From: Edi Weitz
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <ull3gvi2z.fsf@agharta.de>
On Fri, 05 Aug 2005 05:54:35 +0200, Pascal Bourguignon <····@mouse-potato.com> wrote:

> Read the thread.

I have read the thread.  It is pretty clear that you made a
copy-and-paste typo and now refuse to admit it.  How childish...

FWIW, here's your code again that Joel asked about:

  V 5 > (defun * (&rest args)
          (cond ((null args)   (cl:*))
            ((vectorp arg) (apply (function v*)   arg args))
            (t             (apply (function cl:*) arg args))))
  Warning: Syntactic warning for form ARG:
     ARG assumed special.
  *

  V 6 > (* 3 4)

  Error: The variable ARG is unbound.
    1 (continue) Try evaluating ARG again.
    2 Specify a value to use this time instead of evaluating ARG.
    3 Specify a value to set ARG to.
    4 (abort) Return to level 0.
    5 Return to top loop level 0.

  Type :b for backtrace, :c <option number> to proceed,  or :? for other options

Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Pascal Bourguignon
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <87br4cxztn.fsf@thalassa.informatimago.com>
Edi Weitz <········@agharta.de> writes:

> On Fri, 05 Aug 2005 05:54:35 +0200, Pascal Bourguignon <····@mouse-potato.com> wrote:
>
>> Read the thread.
>
> I have read the thread.  It is pretty clear that you made a
> copy-and-paste typo and now refuse to admit it.  How childish...
>
> FWIW, here's your code again that Joel asked about:
>
>   V 5 > (defun * (&rest args)
>           (cond ((null args)   (cl:*))
>             ((vectorp arg) (apply (function v*)   arg args))

Oh, you mean this arg.  Allright.  Sorry.

-- 
"A TRUE Klingon warrior does not comment his code!"
From: Kent M Pitman
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <uslxpxoj4.fsf@nhplace.com>
"Joel Reymont" <······@gmail.com> writes:

> Kent, Paolo,
> 
> Would you kindly give me an example of how I would implement generics
> with compiler macros for + or * or whatever?
> 
> Do I use typecase to expand the generics?
> 
> I do not completely understand generics at this point and how I can
> apply them to this problem. All I understand is that defmethod is a
> simpler version of defgeneric :-).

Generics are way of implementing a function, compiler macros a way of
optimizing them.  They are orthogonal.  Approximately [not tested, 
only approximately written]:

(defpackage "MYMATH"
  (:use "CL")
  (:shadow "*" "+")
  (:export "*" "+"))

(defgeneric mymath:* (thing1 thing2))

(defgeneric mymath:+ (thing1 thing2))

(defmethod mymath:* ((n1 fixnum) (n2 fixnum))
  (cl:* n1 n2))

(defmethod mymath:* ((n fixnum) (v vector))
  (map 'vector #'(lambda (vector-element) (mymath:* n vector-element)) v))

...etc.

(define-compiler-macro mymath:* (&whole form &environment env thing1 thing2)
  (cond ((and (known-return-type-p thing1 'fixnum env)
              (known-return-type-p thing2 'fixnum env))
         `(cl:* ,thing1 ,thing2))
        ...
        (t form))) ;not optimizable, just do generic function call

The problem is finding out how to do the KNOWN-RETURN-TYPE-P, which
you need some support from a vendor to supply because CL has no way to
do it.  You maybe could crudely do:

 (defun known-return-type-p (form type env)
   (or (and (constantp form env)
            (typep (eval form) type))
       (and (consp form)
            (eq (car form) 'the)
            (subtypep type (cadr form)))))

but mostly that would return NIL except for very obscure or trivial
situations.

See the environment manipulation support in CLTL2 for what you probably
really need--i.e., hooks into the system's understanding of declarations.
From: Paolo Amoroso
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <87slxpsch0.fsf@plato.moon.paoloamoroso.it>
"Joel Reymont" <······@gmail.com> writes:

> Say I'm looking to overload + or * to sum or multiple fixnums and
> floats, or vectors of fixnums and floats. This is a trivial example but
> I might want to have specialized versions of the different argument
> permutatios (fixnum + fixnum, fixnum + float, float + float) for
> efficiency.

Maybe compiler macros?


Paolo
-- 
Why Lisp? http://lisp.tech.coop/RtL%20Highlight%20Film
Recommended Common Lisp libraries/tools:
- ASDF/ASDF-INSTALL: system building/installation
- CL-PPCRE: regular expressions
- UFFI: Foreign Function Interface
From: Pascal Costanza
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <3lglbqF12nukdU1@individual.net>
Joel Reymont wrote:
> Folks,
> 
> Say I'm looking to overload + or * to sum or multiple fixnums and
> floats, or vectors of fixnums and floats. This is a trivial example but
> I might want to have specialized versions of the different argument
> permutatios (fixnum + fixnum, fixnum + float, float + float) for
> efficiency.
> 
> How would I do this with Lisp?
> 
> The folks at ITA Software seem to imply in this article
> http://www.paulgraham.com/carl.html that using generics is bad for
> performance.
> 
>     Thanks, Joel

Something like get-effective-method-function could be useful. It doesn't 
"officially" exist, but has been discussed as a potential addition to 
the CLOS MOP. See http://makeashorterlink.com/?G2A212F8B

You could something like this:

(defgeneric myadd (arg1 arg2)
   (:method ((arg1 fixnum) (arg2 fixnum))
     ...)
   (:method ((arg1 float) (arg2 float))
    ...)
   ...)

And then later on:

(let* ((specialized-myadd-methods
         (compute-applicable-methods-using-classes
          #'myadd (list (find-class 'this)
                        (find-class 'that))))
        (special-myadd
         (get-effective-method-function
          #'myadd specialized-myadd-methods)))
   ...
   (funcall special-myadd ...)
   ...)

This would pay off if you use special-myadd several times in the 
enclosed code. (Note, however, that you would lose eql specializers this 
way.)


Pascal

-- 
In computer science, we stand on each other's feet. - Brian K. Reid
From: Thomas F. Burdick
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <xcvy87gojwm.fsf@conquest.OCF.Berkeley.EDU>
Pascal Costanza <··@p-cos.net> writes:

> (let* ((specialized-myadd-methods
>          (compute-applicable-methods-using-classes
>           #'myadd (list (find-class 'this)
>                         (find-class 'that))))
>         (special-myadd
>          (get-effective-method-function
>           #'myadd specialized-myadd-methods)))
>    ...
>    (funcall special-myadd ...)
>    ...)
> 
> This would pay off if you use special-myadd several times in the 
> enclosed code. (Note, however, that you would lose eql specializers this 
> way.)

But even that could be overcome.  You could find all the EQL
specializers that are of the THIS and THAT classes, and setup a nested
CASE around the funcall.  And since we're talking about hypothetical
MOP extensions here, maybe the CLOS system could do it for you, so you
don't screw it up.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Pascal Costanza
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <3lgng2F11vnmoU1@individual.net>
Thomas F. Burdick wrote:
> Pascal Costanza <··@p-cos.net> writes:
> 
>>(let* ((specialized-myadd-methods
>>         (compute-applicable-methods-using-classes
>>          #'myadd (list (find-class 'this)
>>                        (find-class 'that))))
>>        (special-myadd
>>         (get-effective-method-function
>>          #'myadd specialized-myadd-methods)))
>>   ...
>>   (funcall special-myadd ...)
>>   ...)
>>
>>This would pay off if you use special-myadd several times in the 
>>enclosed code. (Note, however, that you would lose eql specializers this 
>>way.)
> 
> But even that could be overcome.  You could find all the EQL
> specializers that are of the THIS and THAT classes, and setup a nested
> CASE around the funcall.  And since we're talking about hypothetical
> MOP extensions here, maybe the CLOS system could do it for you, so you
> don't screw it up.

Sounds like a very good idea to me.


Pascal

-- 
In computer science, we stand on each other's feet. - Brian K. Reid
From: Pascal Costanza
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <3lgr3hF12ef24U1@individual.net>
Pascal Costanza wrote:
> Thomas F. Burdick wrote:
> 
>> Pascal Costanza <··@p-cos.net> writes:
>>
>>> (let* ((specialized-myadd-methods
>>>         (compute-applicable-methods-using-classes
>>>          #'myadd (list (find-class 'this)
>>>                        (find-class 'that))))
>>>        (special-myadd
>>>         (get-effective-method-function
>>>          #'myadd specialized-myadd-methods)))
>>>   ...
>>>   (funcall special-myadd ...)
>>>   ...)
>>>
>>> This would pay off if you use special-myadd several times in the 
>>> enclosed code. (Note, however, that you would lose eql specializers 
>>> this way.)
>>
>> But even that could be overcome.  You could find all the EQL
>> specializers that are of the THIS and THAT classes, and setup a nested
>> CASE around the funcall.  And since we're talking about hypothetical
>> MOP extensions here, maybe the CLOS system could do it for you, so you
>> don't screw it up.
> 
> Sounds like a very good idea to me.

...and this could be a very simple interface:

(confine-generic-function gf specializers)

with

gf - a generic function
specializers - a list of specializers (classes or eql-specializers) for 
the required arguments of the generic function

Yields a function that has the same behavior as gf but confined to the 
given specializers.

The idea is that:

(defmethod compute-discriminating-function
   ((gf standard-generic-function))
   (lambda (&rest args)
     (let* ((arg-classes
             (loop for arg in args
                   for parm in (generic-function-lambda-list gf)
                   until (member parm lambda-list-keywords)
                   collect (class-of arg)))
            (confined-gf
             (confine-generic-function gf arg-classes)))
        (apply confined-gf args))))

...yields a correct discriminating function, and that:

(confine-generic-function
  gf (list ...
           (intern-eql-specializer x)
           ...))

...can even confine a gf to single arguments.

A restriction should be that a confined function does not change when 
the set of methods for the originating generic function changes.

Does that make sense?


Pascal

-- 
In computer science, we stand on each other's feet. - Brian K. Reid
From: RPG
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <1123244490.081953.7690@o13g2000cwo.googlegroups.com>
I looked at Allegro CL 7.0's documentation a little bit and it seems
that one can get access to the environment, including the declarations
there.  I think that's what Kent P was referring to.  So you could use
a compiler macro to get direct application of methods w/o runtime
method dispatch when the declarations were adequate to the purpose.

I don't know whether CMUCL or SBCL would support this and, as
advertised, have only the sketchiest notion about the mechanism in ACL.
 If you have an ACL license, you should probably consult the folks @
Franz.
Cheers,
R
From: Joel Reymont
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <1123246623.008152.90460@g43g2000cwa.googlegroups.com>
RPG, I have asked LispWorks for help with accessing the environment.
There's support for it according to the documentation. I'll post once
they reply. Maybe someone from Franz could post an example of how to do
this with ACL 7.0.

Pascal, I still don't understand where arg came from. I guess I'm on
the same page as Edi.

    Thanks, Joel
From: Edi Weitz
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <uacjwk04a.fsf@agharta.de>
On 5 Aug 2005 05:57:03 -0700, "Joel Reymont" <······@gmail.com> wrote:

> RPG, I have asked LispWorks for help with accessing the environment.
> There's support for it according to the documentation.

Where in the docs did you find that?

> I'll post once they reply.

Yes, please do so.

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Edi Weitz
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <u64ukjzte.fsf@agharta.de>
On 5 Aug 2005 05:57:03 -0700, "Joel Reymont" <······@gmail.com> wrote:

> Maybe someone from Franz could post an example of how to do this
> with ACL 7.0.

Looks like Duane Rettig gave a tutorial at ILC:

  <http://www.international-lisp-conference.org/2005/tutorials.html#making_environments_accessible_in_common_lisp>

Maybe this is available as a paper somewhere.

See also:

  <http://www.franz.com/support/documentation/7.0/doc/environments.htm>

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: RPG
Subject: Re: Overloading in Lisp [ILC 2005 query]
Date: 
Message-ID: <1123252881.460098.29450@f14g2000cwb.googlegroups.com>
As an aside, I would very much like to get hold of any proceedings for
ILC2005, but I haven't been able to get any information (or reply at
all) from anyone connected to ILC.  Does anyone know anything about
proceedings availability?

Thanks,
R
From: Joel Reymont
Subject: Re: Overloading in Lisp [ILC 2005 query]
Date: 
Message-ID: <1123253688.727728.199180@g43g2000cwa.googlegroups.com>
It appears that I was wrong about environment access in LispWorks.
According to Martin Simmons:

Sorry, it isn't possible for two reasons:

1) The environment manipulation support was half baked, both in design
and
implementation.

2) To make this kind of optimization useful, it has to be done long
after
compiler macroexpansion when more information is available.

Someone was kind enough to point me to an example of just what I'm
looking to do, though, and I reposted it below together with a pointer
to the paper that the idea (I believe) came from:

http://wagerlabs.com/uptick/2005/08/overloading-in-lisp.html

    Joel
From: Cameron MacKinnon
Subject: Re: Overloading in Lisp [ILC 2005 query]
Date: 
Message-ID: <_a6dnZ2dnZ2Cg6ScnZ2dnSkXbt-dnZ2dRVn-z52dnZ0@rogers.com>
RPG wrote:
> As an aside, I would very much like to get hold of any proceedings for
> ILC2005, but I haven't been able to get any information (or reply at
> all) from anyone connected to ILC.  Does anyone know anything about
> proceedings availability?

http://international-lisp-conference.org/2005/speakers.html

Scroll down. Slides and/or audio are available for some of the 
presentations.

-- 
Cameron MacKinnon
Toronto, Canada
From: RPG
Subject: Re: Overloading in Lisp [ILC 2005 query]
Date: 
Message-ID: <1123293300.882728.119980@f14g2000cwb.googlegroups.com>
Thanks.  I've seen some of these.  I was hoping for the papers, though,
if they exist....
From: rif
Subject: Re: Overloading in Lisp [ILC 2005 query]
Date: 
Message-ID: <wj0fytngiyl.fsf@five-percent-nation.mit.edu>
"RPG" <·········@gmail.com> writes:

> Thanks.  I've seen some of these.  I was hoping for the papers, though,
> if they exist....

Me too.  Let me say that by the standard of academic conference, one
would really expect the proceedings to be available in some form.
Many conferences actually put their proceedings online for free these
days...

rif
From: Kent M Pitman
Subject: Re: Overloading in Lisp [ILC 2005 query]
Date: 
Message-ID: <ur7d6evyz.fsf@nhplace.com>
rif <···@mit.edu> writes:

> "RPG" <·········@gmail.com> writes:
> 
> > Thanks.  I've seen some of these.  I was hoping for the papers, though,
> > if they exist....
> 
> Me too.  Let me say that by the standard of academic conference, one
> would really expect the proceedings to be available in some form.
> Many conferences actually put their proceedings online for free these
> days...

And sometimes video of the event itself.

But that it is common practice is not proof it is equitable.  It
seriously annoys some of those who have paid good money to attend to
find that the equivalent event is available on video afterward for
much less or sometimes even nothing.  One suddenly realizes that
attending was not about the right to become informed, but about the
right to interact, even though it was not advertised that way.  So
people who don't interact much have to give serious question to
whether they should attend, and conference attendance goes down in
favor of just ordering the video or ordering the proceedings.

As with my rants about free software (with which this one has a great
deal of parallel), I'm not coming out with a blanket statement of
"publishing these materials after is always bad", but I am observing
that there are at least some quantifiable negative impacts of both
publishing proceedings and publishing videos upon the community who
attends when you follow up this way.

Perhaps, in fact, it's good to once in a while not publish stuff, or
defer its publication, or whatever, just to give some added benefit to
those who attended, and, in turn, to give people some incentive to
attend in the future.

I can say for a fact that I tried hard to go to even part of the first
spam conference that Paul Graham's crew had down at MIT.  It was very
over-attended.  It was hard to find seating.  IMO, there were too many
people for any legitimate interactive discussion.  And when I found
out after that there was a video version available after, I just made
up my mind not to try going in the future and to just sit home and
watch it on tape.  As I recall, that one was free or at least
low-cost, and was also so over-attended that some lost attendees did
not matter, so maybe it was best for that one that some stayed home.
But the same effect on Lisp conferences (which struggle to break even,
and where people go on the hopes others will go, and might not go if
they thought others were not going) might not be as beneficial...

When the phenomenon of split-session conferences (something I detest)
first started hitting computer conferences in the mid-1980's (and from
time to time ever since), I came to wonder if it wouldn't be better to
publish the papers separately where people could just order them, then
compress out the time stuck in presentations themselves and just have
a distilled conference of "hallway discussion about the papers", the
main thing some (perhaps many) people go to some conferences for.
(Maybe it would even encourage people to actually read more papers
beforehand if they thought they would come up for discussion.)  Rather
than a several-day conference, under my scheme, you could just spend
all day in one hallway chatting and get as much or more condensed
hallway time than you often get in a conference that's "interrupted"
by people scrambling to get to various sessions.  And the conference
wouldn't even have to rent a big presentation room at great expense.
I guess people would have a harder time getting travel funding from
employers for a conference that was billed as "just standing around
chatting with my buddies"... but it sounded somehow more efficient in
terms of time/money, and perhaps even more intellectually honest.
And it wouldn't leave people asking for the proceedings afterward or
wondering what the difference was between attending and watching from
home... at least until vlogs (video logs) get invented and people
attending start recording ever moment of such an event from every angle
and posting the streaming video indiscriminately to the wwvv (world wide
video vault)...
From: rif
Subject: Re: Overloading in Lisp [ILC 2005 query]
Date: 
Message-ID: <wj0acjukdwa.fsf@five-percent-nation.mit.edu>
I'm not arguing that all conferences "should" publish their
proceedings online for free, merely making the point that many
conferences do so.  I will, however, argue that, in the interests of
tradition ("this is how conferences usually work") and scholarship
("when someone applies for a professor job and says 'I wrote this
paper and it's in the proceedings of this conference', the hiring
committee should have some plausible mechanism to actually track down
the paper"), the proceedings ought to be available in bound form for
reasonable cost, which I would be happy to pay.

I personally would nearly always much prefer the 8-page written paper
to an audio transcription plus slides.
 
rif
From: Pascal Costanza
Subject: Re: Overloading in Lisp [ILC 2005 query]
Date: 
Message-ID: <3lkloeF13c8seU1@individual.net>
rif wrote:
> I'm not arguing that all conferences "should" publish their
> proceedings online for free, merely making the point that many
> conferences do so.

ACM and Springer don't do that. You're probably just enjoying digital 
library accounts payed by the institute you're working at.

It's typically an author's decision whether he/she additionally wants to 
make a paper available online at his/her own website. IIRC, Springer 
asks authors not to do that for about the first year after the official 
publication.

> I will, however, argue that, in the interests of
> tradition ("this is how conferences usually work") and scholarship
> ("when someone applies for a professor job and says 'I wrote this
> paper and it's in the proceedings of this conference', the hiring
> committee should have some plausible mechanism to actually track down
> the paper"), the proceedings ought to be available in bound form for
> reasonable cost, which I would be happy to pay.

Traditionally, it also works well to contact the authors whose papers 
you are interested in. Most of them send you their papers, out of pure 
narcism. ;)


Pascal

-- 
In computer science, we stand on each other's feet. - Brian K. Reid
From: Thomas F. Burdick
Subject: Re: Overloading in Lisp [ILC 2005 query]
Date: 
Message-ID: <xcvek96nlvd.fsf@conquest.OCF.Berkeley.EDU>
Kent M Pitman <······@nhplace.com> writes:

> at least until vlogs (video logs) get invented and people
> attending start recording ever moment of such an event from every angle
> and posting the streaming video indiscriminately to the wwvv (world wide
> video vault)...

Sorry Kent, they already exist.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Duane Rettig
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <4k6iwbfi8.fsf@franz.com>
Edi Weitz <········@agharta.de> writes:

> On 5 Aug 2005 05:57:03 -0700, "Joel Reymont" <······@gmail.com> wrote:
> 
> > Maybe someone from Franz could post an example of how to do this
> > with ACL 7.0.
> 
> Looks like Duane Rettig gave a tutorial at ILC:
> 
>   <http://www.international-lisp-conference.org/2005/tutorials.html#making_environments_accessible_in_common_lisp>
> 
> Maybe this is available as a paper somewhere.

It is, including examples and the code itself:

http://www.lispwire.com/entry-proganal-envaccess-des

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Pascal Costanza
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <3lh9abF12k538U1@individual.net>
Joel Reymont wrote:
> RPG, I have asked LispWorks for help with accessing the environment.
> There's support for it according to the documentation. I'll post once
> they reply. Maybe someone from Franz could post an example of how to do
> this with ACL 7.0.
> 
> Pascal, I still don't understand where arg came from.

I don't understand the question, because it doesn't seem to parse. What 
is it that you don't understand?

> I guess I'm on
> the same page as Edi.

Pascal

-- 
In computer science, we stand on each other's feet. - Brian K. Reid
From: Joel Reymont
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <1123250555.227388.74090@o13g2000cwo.googlegroups.com>
Pascal,

>   V 5 > (defun * (&rest args)
>           (cond ((null args)   (cl:*))
>             ((vectorp arg) (apply (function v*)   arg args))

I mean this arg, the one that you are sorry about. I still don't
understand where it came from.

    Thanks, Joel
From: Joel Reymont
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <1123250854.857138.211620@g44g2000cwa.googlegroups.com>
Edi,

I was referring to this facility in LispWorks:

http://www.lispworks.com/documentation/lw445/LWUG/html/lwuser-54.htm#pgfId-887589

I have no understanding of what it does (which is why I asked LW for
help) but I think I saw a reference to dspec usage with declare
someplace.

    Thanks, Joel
From: Edi Weitz
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <uslxoii9g.fsf@agharta.de>
On 5 Aug 2005 07:07:34 -0700, "Joel Reymont" <······@gmail.com> wrote:

> I was referring to this facility in LispWorks:
>
> http://www.lispworks.com/documentation/lw445/LWUG/html/lwuser-54.htm#pgfId-887589

Ah, I see.  AFAIU this won't help you w.r.t. environment access but
maybe I'm wrong.

From 7.7 of the LispWorks User Guide:

  "The main purpose of the system is to keep track of where the
   definition was located, but it also allows fine-tuned control of
   redefinitions."

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Pascal Bourguignon
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <87zmrwwk2s.fsf@thalassa.informatimago.com>
"Joel Reymont" <······@gmail.com> writes:

> Pascal,
>
>>   V 5 > (defun * (&rest args)
>>           (cond ((null args)   (cl:*))
>>             ((vectorp arg) (apply (function v*)   arg args))
>
> I mean this arg, the one that you are sorry about. I still don't
> understand where it came from.

As Edi indicated, it came from my bad copy-pasting. It should not exist.
Edi corrected the function:

   (defun * (&rest args)
     (cond ((null args) 1)
           ((vectorp (first args)) (apply (function v*) args))
           (t (apply (function cl:*) args))))

I'm sorry for the confusion, I thought the objection came from the
function signature, while it was a question about the body.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
From: Edi Weitz
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <uwtn0iigl.fsf@agharta.de>
On Fri, 05 Aug 2005 15:53:16 +0200, Pascal Costanza <··@p-cos.net> wrote:

> Joel Reymont wrote:
>
>> Pascal, I still don't understand where arg came from.
>
> I don't understand the question, because it doesn't seem to
> parse. What is it that you don't understand?

That was directed towards the other Pascal.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Pascal Costanza
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <3lhb4nF12gk6aU1@individual.net>
Edi Weitz wrote:
> On Fri, 05 Aug 2005 15:53:16 +0200, Pascal Costanza <··@p-cos.net> wrote:
> 
>>Joel Reymont wrote:
>>
>>>Pascal, I still don't understand where arg came from.
>>
>>I don't understand the question, because it doesn't seem to
>>parse. What is it that you don't understand?
> 
> That was directed towards the other Pascal.

Ah, ok.


Pascal

-- 
In computer science, we stand on each other's feet. - Brian K. Reid
From: Thomas F. Burdick
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <xcvr7d7o4o1.fsf@conquest.OCF.Berkeley.EDU>
"RPG" <·········@gmail.com> writes:

> I looked at Allegro CL 7.0's documentation a little bit and it seems
> that one can get access to the environment, including the declarations
> there.  I think that's what Kent P was referring to.  So you could use
> a compiler macro to get direct application of methods w/o runtime
> method dispatch when the declarations were adequate to the purpose.

The problem with environment access is that (compiler-)macroexpansion
it happens at the wrong time in the compilation process.  What you'd
really like is access to the results of both the user's type
declarations *and* the compiler's type inferencing.  Unfortunately, at
least with the Python compiler, the s-expressions are long gone by then.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Nicolas Neuss
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <87zmrwe90o.fsf@ortler.iwr.uni-heidelberg.de>
"Joel Reymont" <······@gmail.com> writes:

> Folks,
>
> Say I'm looking to overload + or * to sum or multiple fixnums and
> floats, or vectors of fixnums and floats. This is a trivial example but
> I might want to have specialized versions of the different argument
> permutatios (fixnum + fixnum, fixnum + float, float + float) for
> efficiency.

I think you will have to avoid generics at this level (even calling a
precomputed effective method would slow you down by a significant factor
unless it is inlined).  Instead, I guess one should try to optimize the
next level, i.e. vector operations.  In Femlisp, I have generated specific
classes for matrices containing a certain type of numbers.  BLAS operations
like DOT invoked on such matrices then generate and compile specialized
methods at runtime.

Example:

;;; The first line generates the class |(STANDARD-MATRIX SINGLE-FLOAT)| and
;;; an instance with entries 1.  Then DOT for class STANDARD-MATRIX does
;;; generate and compile a DOT specialized to |(STANDARD-MATRIX
;;; SINGLE-FLOAT)|.  Later use of DOT does not compile and is fast.

(let ((v (ones 1000 1 'single-float)))
  (dot v v))

Nicolas.
From: Joel Reymont
Subject: Re: Overloading in Lisp
Date: 
Message-ID: <1123255365.850688.323750@g14g2000cwa.googlegroups.com>
Nicolas,

This is exactly my intention, although I don't need to tackle matrices
just yet. Time series are sets of 1d arrays as far as I'm concerned.
Thanks for the pointer, I'll have to look into FemLisp and do the same
when the time comes.

    Thanks, Joel