Re: Polymorphic protocols and containers....

2010-11-05 Thread Christophe Grand
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....

2010-11-05 Thread ataggart
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....

2010-11-05 Thread Christophe Grand
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....

2010-11-04 Thread Mike Meyer
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....

2010-11-04 Thread Ken Wesson
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