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