On Fri, Apr 24, 2009 at 3:36 PM, David Nolen <dnolen.li...@gmail.com> wrote:
> Is this really so hard?

Are you telling me that you routinely write accessors for all your
data structures in Clojure using those macros?  I'll bet very few
people do this.  People make use of the facilities conveniently
available to them.  Unlike Scheme where define-struct gives you all
your accessors for free, Clojure does not (and why should it? It
provides a very versatile interface that applies to all associative
objects).  So people will either use the built-in Clojure way, which
makes use of maps in a fairly non-extensible way, or roll their own
accessor system with varying conventions (is it get-x, or x-get, or
rational-x, namespace/x, etc.?).  Either way sounds problematic to me.

Wouldn't it be even better if you could always use Clojure's standard
accessor/setting syntax, but the meaning of this syntax could be
readily modified for certain types of objects to meet more complex
needs?

There's a broader issue here.  This thread started out with a question
from a newcomer about how to write ADTs in Clojure.  I think if it's
not abundantly clear how to write an ADT in a given programming
language, and there's no consensus on the cleanest way or a set of
very clean ways to do that because most approaches require a certain
amount of "roll-your-own constructor/type
tagging/accessors/implementation hiding" machinations above and beyond
what is easily provided by the language, that's a sign that
programming in that language isn't as easy as it should be.

Put another way, if you were working at a startup about to embark on a
rather large, ambitious programming project in Clojure that would span
many employees and many years, do you feel you have a really solid
handle on exactly how to use Clojure's facilities to architect a
long-lasting, maintainable solution?  How long would you spend
developing standards for coding new data structures?  What do your
constructors look like?  Where do you add the type tag (in the
structure or in the metadata)?  Do you hide any information, and if
so, how?  Do you enforce that employees always make accessors, and if
so, what macro should they use?  How much do you use multimethods to
define your interfaces, versus the Java interface/class system?  How
confident are you that you'd get these decisions right the first time,
rather than making a choice (like a naive solution involving maps)
that will come back to bite you later?

Some of these choices will exist in any language, but the situation is
even more extreme in Clojure, in part because of its newness, and in
part because of Rich's conscious decision to avoid baking in some of
these decisions into the language proper.  And some of the choices are
unique to Clojure because the core constructs and interfaces are
written using a completely different set of idioms (Java classes and
extensions) than typical user code (multimethods over maps as a
polymorphic interface system), and these two approaches don't always
play well together.

I find Clojure delightful for writing small programs, but I don't
think there's a clearcut way yet to follow programming-in-the-large
software engineering principles while sticking with existing Clojure
idioms.  I think any large project would necessarily need to invent a
whole layer on top of the existing facilities, and I find that
unsatisfying.

> I'll also point out that making maps work the way
> you propose isn't even particularly ideal because _anything_ in Clojure can
> be a key not just keywords.
> p.{"first": "Bob", "second": "Smith"} = 5
> Makes absolute no sense in, say, Python, but
> (assoc some-map {:first "Bob" :second "Smith"} 5)
> is perfectly valid in Clojure. How do you propose to reconcile this?
> Just asking ;)

I'm not sure what I said that sounded like it was geared specifically
to keywords as opposed to keys in general.  I can imagine various
solutions to the overall issue.  Perhaps the metadata for a map can
optionally contain a mapping from keys (even complex non-keyword keys
like the one you describe) to custom getter/setter functions, and
core's get and assoc respect those overrides.  Although I see no
problem with these things working on complex keys, in practice, I
suspect that if such facilities existed, they would mostly be used for
keywords in maps that are being used as an implementation for new data
types.

But perhaps hacking more on maps is not the way to go.  Maybe Clojure
needs something new, designed to make ADTs as easy to create as
possible.  Keep the possibilities open, but give users one solid,
clearcut way to do the common case in a scalable way.

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