Re: Defaults for multi-argument dispatch

2009-03-20 Thread Konrad Hinsen

On Mar 20, 2009, at 16:18, Rich Hickey wrote:

>> Providing a :default implementation for multimethods is a very common
>> and useful technique, but it is really useful only for multimethods
>> that dispatch on a single argument.
>
> I disagree about that. No dispatch value, composite or not, is still a
> valid concept.

True, for reasons other than a default in a type hierarchy.

>> But suppose you want to provide a default for one argument only?
>> Something like
>>
>> (defmethod + [java.lang.Integer ::any] ...)
>>
>
> I think it is best to think about this differently than :default, it's
> more about a universal parent than about a missing dispatch value.

It could be seen from both points of view (universal parent in the  
hierarchy, or a partial match with a default), but I agree that the  
universal parent point of view makes more sense.

>> Would it be a good idea to provide the possiblity to add a universal
>> parent to hierarchies? Or would that create any problems? Is there
>> another solution for the situation I described?
>
> Yes, don't know, and no. I briefly looked at this but only got as far
> as to decide Object couldn't be the universal parent. I think you have
> to reserve a value that will never otherwise be used.

Object would indeed not work, the universal parent would have to be  
even above Object.

I just looked at the implementation of hierarchies and I have the  
impression that this should be rather simple to implement. I will try  
and see how it works out in practice.

Konrad.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Defaults for multi-argument dispatch

2009-03-20 Thread Konrad Hinsen

On Mar 20, 2009, at 16:35, Paul Stadig wrote:

> You could use multiple multi-methods:

...

Not pretty, as you said, but also not quite the same in behaviour as  
a single multimethod dispatching on both arguments. Multiple dispatch  
can be made symmetric in the arguments, whereas a chain of  
multimethods always implies a dispatch hierarchy. In your example,  
the type of the first argument always dominates.

Konrad.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Defaults for multi-argument dispatch

2009-03-20 Thread Paul Stadig
It's also not as maintainable as using a single multi-method.

Like I said, not pretty, but it works.


Paul

On Fri, Mar 20, 2009 at 11:38 AM, David Nolen wrote:

> This works well as long as you don't mind the perf hit for the second
> dispatch :)
>
>
> On Fri, Mar 20, 2009 at 11:35 AM, Paul Stadig  wrote:
>
>> You could use multiple multi-methods:
>>
>> user=> (defmulti plus-int (fn [x y] (type y)))
>> #'user/plus-int
>> user=> (defmethod plus-int :default [x y] (println "the first is an int"))
>> #
>> user=> (defmethod plus-int java.lang.Double [x y] (println "one of each"))
>> #
>> user=> (defmulti plus (fn [x y] (type x)))
>> #'user/plus
>> user=> (defmethod plus java.lang.Integer [x y] (plus-int x y))
>> #
>> user=> (plus 1 5)
>> the first is an int
>> nil
>> user=> (plus 1 3.0)
>> one of each
>> nil
>> user=>
>>
>> Not very pretty. (Written backwards courtesy of the REPL ;))
>>
>>
>> Paul
>>
>>
>> On Fri, Mar 20, 2009 at 11:18 AM, Rich Hickey wrote:
>>
>>>
>>>
>>>
>>> On Mar 20, 10:56 am, Konrad Hinsen  wrote:
>>> > Providing a :default implementation for multimethods is a very common
>>> > and useful technique, but it is really useful only for multimethods
>>> > that dispatch on a single argument.
>>>
>>> I disagree about that. No dispatch value, composite or not, is still a
>>> valid concept.
>>>
>>> > What I am looking for is an
>>> > equivalent technique for multiple-argument dispatch.
>>> >
>>> > Suppose you have a multimethod + of two arguments, and you want to
>>> > dispatch on both of them:
>>> >
>>> > (defmulti + (fn [x y] [(type x) (type y)]))
>>> >
>>> > You can then write implementations such as
>>> >
>>> > (defmethod + [java.lang.Integer java.lang.Double] ...)
>>> >
>>> > You can also provide a default implementation, of course:
>>> >
>>> > (defmethod + :default  ...)
>>> >
>>> > But suppose you want to provide a default for one argument only?
>>> > Something like
>>> >
>>> > (defmethod + [java.lang.Integer ::any] ...)
>>> >
>>>
>>> I think it is best to think about this differently than :default, it's
>>> more about a universal parent than about a missing dispatch value.
>>>
>>> > i.e. a multimethod that matches all invocations in which the first
>>> > argument is an integer. I don't currently see a simple way to do
>>> > this. For types in the Java class hierarchy, you can use Object as
>>> > the parent of all types, but there is nothing equivalent in Clojure's
>>> > ad-hoc hierarchies.
>>> >
>>> > Would it be a good idea to provide the possiblity to add a universal
>>> > parent to hierarchies? Or would that create any problems? Is there
>>> > another solution for the situation I described?
>>> >
>>>
>>> Yes, don't know, and no. I briefly looked at this but only got as far
>>> as to decide Object couldn't be the universal parent. I think you have
>>> to reserve a value that will never otherwise be used.
>>>
>>> Rich
>>>
>>>
>>>
>>
>>
>>
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Defaults for multi-argument dispatch

2009-03-20 Thread David Nolen
This works well as long as you don't mind the perf hit for the second
dispatch :)

On Fri, Mar 20, 2009 at 11:35 AM, Paul Stadig  wrote:

> You could use multiple multi-methods:
>
> user=> (defmulti plus-int (fn [x y] (type y)))
> #'user/plus-int
> user=> (defmethod plus-int :default [x y] (println "the first is an int"))
> #
> user=> (defmethod plus-int java.lang.Double [x y] (println "one of each"))
> #
> user=> (defmulti plus (fn [x y] (type x)))
> #'user/plus
> user=> (defmethod plus java.lang.Integer [x y] (plus-int x y))
> #
> user=> (plus 1 5)
> the first is an int
> nil
> user=> (plus 1 3.0)
> one of each
> nil
> user=>
>
> Not very pretty. (Written backwards courtesy of the REPL ;))
>
>
> Paul
>
>
> On Fri, Mar 20, 2009 at 11:18 AM, Rich Hickey wrote:
>
>>
>>
>>
>> On Mar 20, 10:56 am, Konrad Hinsen  wrote:
>> > Providing a :default implementation for multimethods is a very common
>> > and useful technique, but it is really useful only for multimethods
>> > that dispatch on a single argument.
>>
>> I disagree about that. No dispatch value, composite or not, is still a
>> valid concept.
>>
>> > What I am looking for is an
>> > equivalent technique for multiple-argument dispatch.
>> >
>> > Suppose you have a multimethod + of two arguments, and you want to
>> > dispatch on both of them:
>> >
>> > (defmulti + (fn [x y] [(type x) (type y)]))
>> >
>> > You can then write implementations such as
>> >
>> > (defmethod + [java.lang.Integer java.lang.Double] ...)
>> >
>> > You can also provide a default implementation, of course:
>> >
>> > (defmethod + :default  ...)
>> >
>> > But suppose you want to provide a default for one argument only?
>> > Something like
>> >
>> > (defmethod + [java.lang.Integer ::any] ...)
>> >
>>
>> I think it is best to think about this differently than :default, it's
>> more about a universal parent than about a missing dispatch value.
>>
>> > i.e. a multimethod that matches all invocations in which the first
>> > argument is an integer. I don't currently see a simple way to do
>> > this. For types in the Java class hierarchy, you can use Object as
>> > the parent of all types, but there is nothing equivalent in Clojure's
>> > ad-hoc hierarchies.
>> >
>> > Would it be a good idea to provide the possiblity to add a universal
>> > parent to hierarchies? Or would that create any problems? Is there
>> > another solution for the situation I described?
>> >
>>
>> Yes, don't know, and no. I briefly looked at this but only got as far
>> as to decide Object couldn't be the universal parent. I think you have
>> to reserve a value that will never otherwise be used.
>>
>> Rich
>>
>>
>>
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Defaults for multi-argument dispatch

2009-03-20 Thread Paul Stadig
You could use multiple multi-methods:

user=> (defmulti plus-int (fn [x y] (type y)))
#'user/plus-int
user=> (defmethod plus-int :default [x y] (println "the first is an int"))
#
user=> (defmethod plus-int java.lang.Double [x y] (println "one of each"))
#
user=> (defmulti plus (fn [x y] (type x)))
#'user/plus
user=> (defmethod plus java.lang.Integer [x y] (plus-int x y))
#
user=> (plus 1 5)
the first is an int
nil
user=> (plus 1 3.0)
one of each
nil
user=>

Not very pretty. (Written backwards courtesy of the REPL ;))


Paul

On Fri, Mar 20, 2009 at 11:18 AM, Rich Hickey  wrote:

>
>
>
> On Mar 20, 10:56 am, Konrad Hinsen  wrote:
> > Providing a :default implementation for multimethods is a very common
> > and useful technique, but it is really useful only for multimethods
> > that dispatch on a single argument.
>
> I disagree about that. No dispatch value, composite or not, is still a
> valid concept.
>
> > What I am looking for is an
> > equivalent technique for multiple-argument dispatch.
> >
> > Suppose you have a multimethod + of two arguments, and you want to
> > dispatch on both of them:
> >
> > (defmulti + (fn [x y] [(type x) (type y)]))
> >
> > You can then write implementations such as
> >
> > (defmethod + [java.lang.Integer java.lang.Double] ...)
> >
> > You can also provide a default implementation, of course:
> >
> > (defmethod + :default  ...)
> >
> > But suppose you want to provide a default for one argument only?
> > Something like
> >
> > (defmethod + [java.lang.Integer ::any] ...)
> >
>
> I think it is best to think about this differently than :default, it's
> more about a universal parent than about a missing dispatch value.
>
> > i.e. a multimethod that matches all invocations in which the first
> > argument is an integer. I don't currently see a simple way to do
> > this. For types in the Java class hierarchy, you can use Object as
> > the parent of all types, but there is nothing equivalent in Clojure's
> > ad-hoc hierarchies.
> >
> > Would it be a good idea to provide the possiblity to add a universal
> > parent to hierarchies? Or would that create any problems? Is there
> > another solution for the situation I described?
> >
>
> Yes, don't know, and no. I briefly looked at this but only got as far
> as to decide Object couldn't be the universal parent. I think you have
> to reserve a value that will never otherwise be used.
>
> Rich
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Defaults for multi-argument dispatch

2009-03-20 Thread Rich Hickey



On Mar 20, 10:56 am, Konrad Hinsen  wrote:
> Providing a :default implementation for multimethods is a very common
> and useful technique, but it is really useful only for multimethods
> that dispatch on a single argument.

I disagree about that. No dispatch value, composite or not, is still a
valid concept.

> What I am looking for is an
> equivalent technique for multiple-argument dispatch.
>
> Suppose you have a multimethod + of two arguments, and you want to
> dispatch on both of them:
>
> (defmulti + (fn [x y] [(type x) (type y)]))
>
> You can then write implementations such as
>
> (defmethod + [java.lang.Integer java.lang.Double] ...)
>
> You can also provide a default implementation, of course:
>
> (defmethod + :default  ...)
>
> But suppose you want to provide a default for one argument only?
> Something like
>
> (defmethod + [java.lang.Integer ::any] ...)
>

I think it is best to think about this differently than :default, it's
more about a universal parent than about a missing dispatch value.

> i.e. a multimethod that matches all invocations in which the first
> argument is an integer. I don't currently see a simple way to do
> this. For types in the Java class hierarchy, you can use Object as
> the parent of all types, but there is nothing equivalent in Clojure's
> ad-hoc hierarchies.
>
> Would it be a good idea to provide the possiblity to add a universal
> parent to hierarchies? Or would that create any problems? Is there
> another solution for the situation I described?
>

Yes, don't know, and no. I briefly looked at this but only got as far
as to decide Object couldn't be the universal parent. I think you have
to reserve a value that will never otherwise be used.

Rich

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---