Re: Multimethods derive
On 08.06.2009, at 04:26, Stuart Sierra wrote: If it is, it would be very useful to have something that is the ancestor of everything (like T in common lisp). This has been thought about, at least: http://clojure.org/todo I think the question is... what should the universal ancestor be? For classes, it's java.lang.Object. But derive allows you to create relationships outside the Java class hierarchy. So for now, defining your own root ancestor is the way to proceed. See also my patch that creates such a universal root type (the keyword :root): http://groups.google.com/group/clojure/browse_thread/thread/ bc5193304c1ab2e3/77e5d53d8ccd6b10?lnk=gstq=%3Aroot#77e5d53d8ccd6b10 Of course, it is not a good idea to write code relying on an unofficial patch, I don't even use it myself for production code. But the patch illustrates that this can be done, and my tests have not shown any undesirable side effects. 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 Note that posts from new members are moderated - please be patient with your first post. 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: Multimethods derive
On Jun 8, 3:51 pm, Konrad Hinsen konrad.hin...@laposte.net wrote: See also my patch that creates such a universal root type [...] Nice! That's exactly what I was thinking about Peter --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. 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 -~--~~~~--~~--~--~---
Multimethods derive
Hi, I would like to use multimethods by dispatching on keys of the variables (maps) in a way that I sometimes have constraints on only some of the arguments. In common lisp I would say (defgeneric foo (a b)) (defmethod foo ((a bar) b) ...) (defmethod foo (a (b baz)) ...) (defmethod foo ((a bar) (b baz)) ...) This would mean that I have also defined methods for calls when (for example) `a' is an instance of `bar' and `b' of anything but `baz'. How can I achieve something like this with multimethods? I could define a relationship like (derive :bar :anything) (derive :baz :anything) and then do (defmulti foo (fn [a b] [(:somekey1 a) (:somekey2 b)])) with (defmethod foo [:bar :anything] [a b] ...) (defmethod foo [:anything :baz] [a b] ...) (defmethod foo [:bar :baz] [a b] ...) This seems to do the trick... but is this really the way to do it? If it is, it would be very useful to have something that is the ancestor of everything (like T in common lisp). Thanks, Peter --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. 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: Multimethods derive
On Jun 7, 7:46 pm, Peter Salvi salvipe...@gmail.com wrote: (defmethod foo [:bar :anything] [a b] ...) (defmethod foo [:anything :baz] [a b] ...) (defmethod foo [:bar :baz] [a b] ...) This seems to do the trick... but is this really the way to do it? This looks reasonable. If it is, it would be very useful to have something that is the ancestor of everything (like T in common lisp). This has been thought about, at least: http://clojure.org/todo I think the question is... what should the universal ancestor be? For classes, it's java.lang.Object. But derive allows you to create relationships outside the Java class hierarchy. So for now, defining your own root ancestor is the way to proceed. -Stuart Sierra --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. 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 -~--~~~~--~~--~--~---
multimethods + derive question
Hi all, I am working on the multimethod chapter this week. This has required a lot of exploration, as the multimethod feature set goes well beyond what most people are using yet. I have hit one rough spot: derive. I have working code (below), but I don't like the way I have to call it with fully qualified keywords, e.g. (service-charge {:tag :examples.multimethods.service-charge-3/ checking :balance 100}) - 25 (service-charge {:tag :examples.multimethods.service-charge-3/ checking :balance 1}) - 0 I feel that I have made a wrong turn somewhere. Here are my assumptions: 1. I (the implementer) have to write my dispatch functions with qualified names, if I want to use derive. 2. John Doe (the caller) must use fully qualified names *everywhere*. Since he does not live in my namespace he cannot use the ::. It's the latter that bothers me. It seems so ugly that I would never use hierarchical names for anything, which makes me think I am missing something. To make matters worse: 3. Once I use :: once on any keyword in my implementation, it is a quick slope to using it other places too, just so I don't have to remember which ones I chose to qualify and which ones I didn't. In the code below, :premium and :basic become ::premium and ::basic just for consistency with ::checking and ::savings. Is anybody else working with derive? What are your experiences? Thanks, Stu --- (ns examples.multimethods.service-charge-3) (defmulti account-level :tag) (println ::checking) (defmethod account-level ::checking [acct] (if (= (:balance acct) 5000) ::premium ::basic)) (defmethod account-level ::savings [acct] (if (= (:balance acct) 1000) ::premium ::basic)) (derive ::savings ::account) (derive ::checking ::account) (defmulti service-charge (fn [acct] [(account-level acct) (:tag acct)])) (defmethod service-charge [::basic ::checking] [_] 25) (defmethod service-charge [::basic ::savings][_] 10) (defmethod service-charge [::premium ::account] [_] 0) --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: multimethods + derive question
Rich, Very helpful, as always. Alias + the ability to pull in symbols names via refer was exactly what I was looking for. One scenario still worries me: 1. I create a multimethod that dispatches around a tag whose value is an unresolved keyword (:Foo instead of ::Foo). Everything works fine. 2. If at some later point I want the dispatch to depend on (derive), it is breaking change for clients to switch to from :Foo to ::Foo. I am tempted to conclude that you should never use unqualified keywords as type tags, because you are exposing an implementation detail. That is, the implementation promises not to rely on derive. Cheers, Stuart --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---