This answer says everything I would want to say better than I would say it. Second!
Alex On Wednesday, June 25, 2014 9:12:01 PM UTC-5, Ryan Schmitt wrote: > > In object-oriented programming, encapsulation is always and everywhere > regarded as a highly significant design virtue, but the Clojure people have > a bit of a different assessment, particularly when it comes to information. > In one talk, Rich Hickey pointed out that encapsulation is for hiding > implementation details, but information doesn't *have* an implementation; > there are no innards to encapsulate *unless you add them*. Stuart > Halloway gave one talk where he made a brilliant point about how > abstraction is valuable for *commands*, because then it limits what you > have to know, but it's not valuable for *queries*, because then the > abstraction (i.e. the custom accessors that "encapsulate" your data) only > limits what you can perceive. > > And of course, there's Alan Perlis's old saw that "it is better to have a > hundred functions operate on one data structure than to have ten functions > operate on ten data structures"--that is to say, by using generic data > structures (e.g. maps) to directly represent information in your domain, > you can reuse all of the generic functions that operate on those data > structures, whereas encapsulated data screws your clients because it > renders all of their generic collections libraries useless. (This is one of > the ways in which OOP has failed to deliver on its promise of pervasive > code reuse.) > > Some of Rich Hickey's talks that touch on the subject: > > http://www.infoq.com/presentations/Value-Values > http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey > > As for your particular example, I recommend looking at defrecord, which > generates a data structure that behaves like a map (it can be perceived and > manipulated generically), as well as various constructors and readers and > so forth for that type. defrecord also lets you specify protocols for your > data type. See: > > http://clojure.org/datatypes > > Also be sure to check out Prismatic's survey of Clojure's choices for > doing "object"-like things: > > > https://github.com/Prismatic/eng-practices/blob/master/clojure/20130926-data-representation.md#data-types > > On Wednesday, June 25, 2014 6:34:50 PM UTC-7, Mark P wrote: >> >> I've only recently started real clojure development, so very much still >> learning what styles work and what don't. I have a question about naming >> attribute getters... >> >> Suppose I want to model "fruit" entities. I will use a hash-map to >> represent the data for each such entity, and will defn a "make" function to >> construct fruit instances. I will put "make" and any other fruit-related >> functions within a new namespace "myprog.fruit". >> >> Because my data representation is a map, strictly speaking I don't need >> any attribute getter functions. Because I could simply use the attribute >> keywords in the map as my getter functions, eg (:color fru). But I will >> create actual getter functions within my namespace anyway, for a few >> reasons. >> >> 1. It will signal to any users of my fruit library, which attributes >> are "official" and are expected to be used / supported, versus attributes >> which are more of an implementation detail. >> 2. Some attributes will simply be (defn color [fru] (:color fru)), >> whereas others are less direct, eg (defn red? [fru] (= :red fru)) or >> another eg (defn packingvol [{:keys [size]}] (* size size size)). >> 3. Down the track I can change my data representation, and just >> reimplement the getter functions. Users of my fruit library who have >> stuck >> to my getter functions interface will not need to change a thing. >> >> This approach seems okay to me so far, though I am open to critiques and >> alternative suggestions. But one issue has come to mind... leading to the >> question of this post... >> >> At the end of 2. above, I have defined a local let symbol "size" as part >> of the map destructuring. But it so happens I have already defined a size >> getter, namely (defn size [fru] (:size fru)). So within the definition of >> packingvol my size getter is masked by the local symbol "size". Now I'm >> not sure this masking causes much harm... I don't actually need to use the >> size getter here, and if I really needed it I could always use >> "myprog.fruit/size"... But something still makes me feel uncomfortable >> about it, maybe because this masking could end up happening a lot within my >> fruit.clj source code file. >> >> Now I could just switch to a new naming convention for my getters, ie >> "color-get", "red?-get", "size-get", "packingvol-get" etc. But I'm not >> sure I like the extra verbosity. And for users of my fruit library - who >> will be working in a different namespace - this problem mostly goes away as >> they will probably be namespace-qualifying access to my getters. >> >> Is using self-named attribute getters a good idea? >> >> Thanks, >> >> Mark. >> >> -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.