deftype
acts as the abstract container, extending one or more protocolsdefmulti
that is used within the deftype form act as abstract methods:type
).I guess I'm wondering why take Zheng's approach, versus something more direct? I'm especially reacting to this:
One way to look at design using abstract classes (or any language feature for that matter) is that it is a programming contract that is strictly enforced by the language itself. When we inherit functionality from an abstract class, we make a binding contract with the compiler.
…Essentially, it mimics the structure of how abstract classes are defined and used in object orientated design through simple use of protocols and multimethods.
But why mimic such a contract? Why not just clearly write a contract, using a library that is meant to write contracts? I mean, why not use something like Typed Clojure?
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
The example in the article is probably the smallest example I can come up with.The code for the concrete implementations speaks for itself I think, it is about 10 lines to hook in jetty and http-kit to the framework.
(defn multi-element [m v] | |
(element {:tag :multi | |
:name (get-name v) | |
:array v | |
:lookup m | |
:cache (atom {})})) |
(defmethod to-element clojure.lang.APersistentMap [m] | |
(let [v (to-element-array m)] | |
(multi-element m v))) |
(defmethod to-element clojure.lang.APersistentVector [v] | |
(let [m (reduce | |
(fn [m ele] | |
(assoc-in m (to-element-map-path ele) ele)) | |
{} v)] | |
(multi-element m v))) |
James: For sure. To be honest, I haven’t really thought too much about best practices. The code just naturally evolved in this way. Let me have a think about this over the weekend and come up with something.
Lawrence: I see what you are saying… and again, I need some time to think about the implications. It’s interesting for me to be able look at this in hindsight and really question the value of why I did this in a certain way..
As context, I didn’t start with the pattern and tried to fit things to it… I wrote a code bunch of code, refactored it a couple of times, and found commonalities in design that I was able to extract into what is now being discussed. So it’s really a case of tomaYtos, toMAAtos - a question of taste - and I think we are really lucky that clojure allows for all types =)