Re: Defaults for multi-argument dispatch
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
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
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
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
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
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 -~--~~~~--~~--~--~---