Re: Polymorphic protocols and containers....
On Fri, Nov 5, 2010 at 1:39 AM, Mike Meyer mwm-keyword-googlegroups.620...@mired.org wrote: It seems like the polymorphism of protocols breaks inside the methods. This is a problem for having a function that's polymorphic between an object and a container of the same objects. For instance: user= (defprotocol Tune (tweek [this])) Tune user= (deftype Knob [name] Tune (tweek [this] (println Tweeked name))) user.Knob user= (def base (Knob. base)) #'user/base user= (tweek base) Tweeked base nil user= (def treble (Knob. treble)) #'user/treble user= (tweek treble) Tweeked treble nil user= (deftype Box [ knobs] Tune (tweek [this] (for [knob knobs] (tweek knob this vector is not an argument list but a field list, so you are defiing to fields, one named and one named knobs. Try to evaluate (.name (.knobs (Box. base treble))) and you'll see that knobs only holds treble. if you fix it: (deftype Box [knobs] Tune (tweek [this] (for [knob knobs] (tweek knob then: (tweek (Box. [base treble])) will work as expected. If you really want var-args, you just have to write a factory fn (defn box [ knobs] (Box. knobs)) hth, Christophe -- 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: Polymorphic protocols and containers....
Do you know of a reason why (deftype [foo more]) isn't read in as having two fields where the second is a seq? Barring that, would it be reasonable to disallow as a valid field name, thus preventing this class of error? On Nov 4, 11:54 pm, Christophe Grand christo...@cgrand.net wrote: On Fri, Nov 5, 2010 at 1:39 AM, Mike Meyer mwm-keyword-googlegroups.620...@mired.org wrote: It seems like the polymorphism of protocols breaks inside the methods. This is a problem for having a function that's polymorphic between an object and a container of the same objects. For instance: user= (defprotocol Tune (tweek [this])) Tune user= (deftype Knob [name] Tune (tweek [this] (println Tweeked name))) user.Knob user= (def base (Knob. base)) #'user/base user= (tweek base) Tweeked base nil user= (def treble (Knob. treble)) #'user/treble user= (tweek treble) Tweeked treble nil user= (deftype Box [ knobs] Tune (tweek [this] (for [knob knobs] (tweek knob this vector is not an argument list but a field list, so you are defiing to fields, one named and one named knobs. Try to evaluate (.name (.knobs (Box. base treble))) and you'll see that knobs only holds treble. if you fix it: (deftype Box [knobs] Tune (tweek [this] (for [knob knobs] (tweek knob then: (tweek (Box. [base treble])) will work as expected. If you really want var-args, you just have to write a factory fn (defn box [ knobs] (Box. knobs)) hth, Christophe -- 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: Polymorphic protocols and containers....
On Fri, Nov 5, 2010 at 8:23 AM, ataggart alex.tagg...@gmail.com wrote: Do you know of a reason why (deftype [foo more]) isn't read in as having two fields where the second is a seq? deftype is low level and exposes limitations of the host and constructors should not be exposed directly (add a new field, change the field ordering and you'll have to fix all the constructor calls) but through a factory fn. Barring that, would it be reasonable to disallow as a valid field name, thus preventing this class of error? It sounds reasonable. Christophe -- 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
Polymorphic protocols and containers....
It seems like the polymorphism of protocols breaks inside the methods. This is a problem for having a function that's polymorphic between an object and a container of the same objects. For instance: user= (defprotocol Tune (tweek [this])) Tune user= (deftype Knob [name] Tune (tweek [this] (println Tweeked name))) user.Knob user= (def base (Knob. base)) #'user/base user= (tweek base) Tweeked base nil user= (def treble (Knob. treble)) #'user/treble user= (tweek treble) Tweeked treble nil user= (deftype Box [ knobs] Tune (tweek [this] (for [knob knobs] (tweek knob user.Box user= (tweek (Box. base treble)) user= (tweek (Box. base treble)) java.lang.IllegalArgumentException: Don't know how to create ISeq from: user.Knob (user= Where what I really want to happen is to tweek all the knobs in the box. Unfortunately, tweek inside the method seems to be wired to the method it's in, and no longer polymorphic. I've tried various ways to get to the variable I want, and some hinting, but nothing seems to change what I'm getting here. Maybe I shouldn't be trying to use protocols and types for this? Can someone let me know what I need to do to make this happen? Thanks, mike -- Mike Meyer m...@mired.org http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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: Polymorphic protocols and containers....
user= (defn tweek* [knob] (tweek knob)) #'user/tweek* user= (tweek* base) Tweeked base nil user= (deftype Box [ knobs] Tune (tweek [this] (for [knob knobs] (tweek* knob user.Box user= (tweek (Box. base treble)) #IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: user.Knob Not lexical scope, then -- it's not the deftype macro redefining it lexically or that wouldn't make tweek* stop working. user= (defn tweek* [knobs] (pmap #(tweek %) knobs)) #'user/tweek* user= (tweek (Box. base treble)) #CompilerException java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: user.Knob (NO_SOURCE_FILE:28) Even more interesting. It's not being thread-locally rebound, either. It's being globally rebound. user= (deftype Box [ knobs] Tune (tweek [this] (println this) (tweek* knobs))) user.Box user= (tweek (Box. base treble)) #Box user@fe7f80 #CompilerException java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: user.Knob (NO_SOURCE_FILE:30) Fascinating. It's not calling the Box tweek on the Box, then calling the Box tweek again on the knobs, else we'd have seen #Box user@fe7f80 #Knob user.k...@fa6824 #CompilerException java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: user.Knob as it called tweek on the Box, printed the box, called tweek* which mapped over the knobs, tweek got called on the base knob, printed the base knob, and then tried to pmap over the base knob which isn't an ISeq. It's doing something else but I don't know what and I've got to go, sorry. Fringe is on. -- 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