On Aug 14, 12:34 am, Stuart Halloway <stuart.hallo...@gmail.com>
wrote:
> > Following Stuart's suggestion, I *could* just add a protocol
> > called "PrettyPrintable" with one method and implement it on some
> > of the new node types, but now I can't just call "pretty-print" on
> > any node: I need to write another function that checks if it's a
> > PrettyPrintable first and calls something default if not.
>
> You can just extend PrettyPrintable to Object.

Just to thrash this out in my own head I've developed the scenario
below as a hypothetical (and obviously trivial) graph node library
evolves through several versions. I've used extend-type on Object to
retro-actively provide default implementations for older clients.

Adding to Object works, but doesn't feel right: as libraries grow,
they'll start bloating out the method sets on the global Object type.

One idea that I tried was to use extend-type on a protocol, say to
extend any Node to be a PrettyPrintableNode. Obviously this didn't
work, and I'm not sure it actually makes semantic sense, but it's
interesting that was my intuitive action.

Example below, interested in any thoughts.

Matthew.

---

;; A node has a data attachment and (possibly) children
(defprotocol Node
  (data [n])
  (children [n]))

(deftype SimpleNode [d]
  Node
  (data [n] d)
  (children [n] []))

;; In version 2, I add want to add pretty-printing

(defprotocol PrettyPrintableNode
  (pretty-print [n]))

;; Make anything potentially pretty-print'able
(extend-type Object
  PrettyPrintableNode
  (pretty-print [n] (str "A node: " (data n))))

;; Later, in version 3, I decide nodes also need a tag

(defprotocol TaggedNode
  (tag [n]))

;; Default to node's data if no tag
(extend-type Object
  TaggedNode
  (tag [n] (data n)))

;; A new type of node that has a settable tag
(deftype SuperNode [d t]
  Node
  (data [n] d)
  (children [n] [])

  PrettyPrintableNode
  (pretty-print [n] (str "Node: tag " (tag n)
                     ", data: " (data n)))

  TaggedNode
  (tag [n] t))

---

Examples of use

> (def n  (SimpleNode. "Matt"))
> (def n2 (SuperNode. "Matt" "a tag"))
> (tag n)
"Matt"
> (tag n2)
"a tag"
> (pretty-print n2)
"Node: tag a tag, data: Matt"
> (pretty-print n)
"A node: Matt"

-- 
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

Reply via email to