On Feb 25, 2009, at 17:40, David Nolen wrote:

> Should print and println be multimethods? It seems the ability to  
> custom print a data structure would be generally useful.

It's already there, just not documented as far as I know. All the  
printing routines end up calling clojure.core/print-method and  
clojure.core/print-dup, which are multimethods dispatching on class.

> Not totally following here, looking at your code... Pardon my  
> slowness but why not dispatch on :tag first, and class if no :tag?

That's possible, of course, but the result is a multimethod that  
works for (a) class-based types and (b) one specific type hierarchy  
hard-wired into the selector, such as your :tag. If I write some  
other type system, it won't fit in. That makes it impossible to  
define truly general interfaces that are open for anyone to implement.

Take print-method in clojure.core as an example: How would you  
implement its selector, such that anyone could plug in their type  
system based on some tagging scheme? Perhaps one could come up with a  
scheme in which the selector function is itself a multimethod, but  
that would probably be quite messy.

> Tags of course should be namespaced so is this really that much of  
> an issue in practice? Since tags are keywords they don't have the  
> interning conflict problem that symbols of the same name generally  
> do, right?

Right. Namespaced tags go a long way to avoid name clashes. However,  
they are still not the private property of any one library module.  
Your namespaced tag is an object that can end up in any data  
structure, intentionally or by error. Only time will tell if this is  
a problem in practice.


Anyway, my two main arguments in this issue are printing and open-to- 
anyone interfaces with multimethods. These are the problems that I  
had in my own code and that I wanted to solve. Printing is important  
for complex nested data structures and interactive use. Generic  
interfaces are a very nice feature to have. I came across this  
problem twice:

1) In clojure.contrib.accumulators. Ideally, it should be possible to  
implement additional accumulator types elsewhere, using the same  
interface. With the current implementation based on meta-data, that  
is possible, but only for data types that allow meta-data. It is thus  
not possible to build accumulators based on Java classes, at least  
not without wrapping them in a map or vector. Moreover, the selector  
function, based on meta-data with a fallback to classes, is neither  
elegant nor efficient, and much of the code in the library deals with  
the meta-data tagging scheme rather than with its real job.

2) In clojure.contrib.streams-utils. Again, I wanted to define a  
generic interface to data streams. At the moment, it uses a  
multimethod dispatching on class, but that doesn't leave much room to  
define different data stream sources. That was in fact what prompted  
me to write the types library.

Konrad.


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