On Fri, Nov 13, 2009 at 2:13 AM, Krukow <karl.kru...@gmail.com> wrote: > > > On Nov 12, 1:10 pm, Rich Hickey <richhic...@gmail.com> wrote: >> An early version of the code for a few important new language >> features, datatypes[1] and protocols[2] is now available in the 'new' >> branch[3]. Note also that the build system[4] has builds of the new >> branch, and that the new branch works with current contrib. >> >> If you have the time and inclination, please try them out. Feedback is >> particularly welcome as they are being refined. > > I really like the semantics of your constructs. I have a comment about > regularity of syntax: > > The way to specify method names in reify and deftype vs. function > names defprotocol and extend are different.
That's because methods and functions *are* different. I think making them look the same only makes it more confusing since: - methods can only be defined by the definer of a type, protocol extension fns can be defined by anyone anywhere - methods have class scope - direct use of fields as locals, functions must use (:field self) - functions are first class values and can be put in maps etc, methods can't - methods have implicit this, functions don't - functions can be closures, methods, other than in reify, can't > It looks like when dealing > with interface-method implementations one uses .methodName (i.e., with > the dot), but when dealing with protocol functions one uses no dot. > Further, extend uses maps (the docs says why this is the case). > > I was thinking this may make syntax irregular. I suspect this is a > deliberate design choice to distinguish clojure protocols from java > interfaces? Is this the case? Yes. > > A stupid example: > > ;;uses dot > (deftype Sometype [x] > [java.lang.Comparable] > (.compareTo [o] ...)) > > ::uses no dot > (defprotocol RSeqable :on clojure.lang.Seqable > "Seqable and reverse seqable" > (rseq [s] "reverse seq")) > > ;;do I mix dot and not? > (extend ::Sometype > :RSeqable > {:rseq (fn [a]...)) > :.seq (fn [a] ...)} ;; do I write :.seq here or :seq? > You don't mix methods and protocol functions, so once that is clear I don't think this will be a question. In a sense, deftypes and protocols are bridging two polymorphism systems. As long as one doesn't conflate the two, it becomes clearer. For instance, you could use deftype and protocols in complete ignorance/avoidance of Java and interfaces: (deftype Foo [a b c]) (defprotocol P (bar [x] "bar docs")) (extend ::Foo P {:bar (fn [afoo] :foo-thing)}) (bar (Foo 1 2 3)) :foo-thing This is a simple, powerful, flexible and dynamic system, leveraging one's understanding of Clojure functions. If and only if there is some requirement that instances of Foo implement some Java interfaces, then you will need to understand Java interfaces and methods. And there will be a clear mechanism and place to put them - in your deftype, just like methods have to be put inside class definitions in Java. You have similar class scope for fields and access to this, etc. One thing you do not have is implicit scope for methods, the leading dot helps remind you that in order to call someMethod, even in the body of another method in the same deftype, you will have to use (.someMethod this ...). People have argued against implicit this for similar reasons, and I am starting to come around :) The documentation is comprehensive in mentioning everything you can do. But one doesn't need to use everything. 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 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