Laurent, I think we're actually mostly in agreement here, although we
differ on some of the details.

I agree with the Principle of Uniform Access.  One interpretation of
this principle is that coders should never have a public field, and
should always use getters and setters, to make the API future proof.
This is how Java does things (or has it improved in latest versions?),
but many programmers (including myself) don't like this.  So most
recent languages (C#, Scala) let you start out with public fields, and
then later, you can create methods which are actually called under the
covers by the standard assignnment and lookup mechanism in the
language, disguising these dynamic properties as standard fields.  The
point is, you start out using the simplest thing to express your data
structure, and then you can convert it effortlessly IF you end up
needing to.

In Clojure, most new data structures are going to be implemented as a
map.  I am well aware that you could define getters and setters for
every single field to protect yourself.  But I would prefer to start
with the simplest possible implementation, and be able to grow it
gracefully if need be.  In other words, I want to start out just
representing my data structure as a map.  I want to be able to use the
wonderfully convenient notations that Clojure allows (e.g.,
(:numerator rational) to look up the numerator in a structure
representing a rational number).  And then, I want my client code to
*not break* when my needs grow.

In Clojure, you can do amazing things with maps, making it an ideal
tool for rapid coding, especially in the initial phase where
interfaces and design needs change frequently.  At the other end of
the spectrum, you can also code elaborately complex things as Java
classes, interfaces, and proxies to implement them.  But there isn't
much you can do in between.  If you start with a map, and your needs
grow, you're kind of stuck and need to do a pretty elaborate rewrite.
It seems to me there's a need for something that works like a map,
letting you continue to use the standard associative interface such as
get, assoc, keyword access notation, =, etc., but can handle slightly
more complex things, perhaps with better hooks for customizing
equality, or hiding certain parts of the map, or providing a special
function to be called when using assoc and get with certain keywords
on a given map.

On Fri, Apr 24, 2009 at 9:46 AM, Laurent PETIT <laurent.pe...@gmail.com> wrote:
> Why do you say "things kind of break down" ?
>
> (:key my-map) is a function call ? Everything is always (almost) a
> function call in clojure ?

Yes, but as far as I know, it doesn't call anything you can customize.
 I believe it calls get, which you can't hook into without
reimplementing your data structure as a proxy for the associative
interface.

>
> I think an idea could be to have (get) and (set) polymorphic via
> multimethods (if they aren't already, maybe I don't know), but that
> would certainly be a performance killer ?

Yes, if all the built-in things were implemented as multimethods, a
lot of my extensibility/scalability concerns would go away.  But they
aren't (presumably for performance reasons).  They are implemented as
Java interfaces, and you can't easily make a map respond differently
to these interfaces.  You have to custom code your own map-like thing
via proxy.  And equality and hashing are even more difficult to
customize.

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