Style - Keyword access or accessors?

352 مرّة مشاهدة
التخطي إلى أول رسالة غير مقروءة

Colin Yates

غير مقروءة،
22‏/04‏/2014، 5:43:53 ص22‏/4‏/2014
إلى clo...@googlegroups.com
(This has been discussed before but as this is fairly subjective I am interested in whether people's opinion has changed)

What are people's experiences around using keywords or defined accessors for navigating data structures in Clojure (assuming the use of maps)?  Do people prefer using "raw" keywords or do people define accessors.

For example, given {:my-property 10} would people inline "my-property" or define a (defn my-property [m] (:my-property m))?  If you use keywords then do you alias them (i.e. (def my-property :my-property)?

My experience is that accessors become painful and restrictive really quickly (navigating nested maps for example) so keywords are the way to go.  I tend to have a domain.clj which documents my domain and defines all the important abstractions (i.e. (def my-property :my-property).  I find this very useful, combined with marginalia for documentation purposes.  It also offers some aid in refactoring as multiple abstractions might resolve to the same keyword (i.e. value-group and bracket-group might resolve to :group).

But, to be blunt, it can be a little cumbersome.  I also refer :as the namespace, so instead of (get-in m [:a :b]) it is (get-in m [dom/a dom/b]).

What are your thoughts (and any other hints/tips for maintaining large Clojure code bases?)

Daniel Kersten

غير مقروءة،
22‏/04‏/2014، 5:49:33 ص22‏/4‏/2014
إلى clo...@googlegroups.com
I've personally always used keywords. I don't see any value in aliasing :foo to foo. For navigating nested maps, get-in, update-in and assoc-in with keywords seem natural and practical to me.


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Colin Yates

غير مقروءة،
22‏/04‏/2014، 6:06:38 ص22‏/4‏/2014
إلى clo...@googlegroups.com
Thanks Dan,

One benefit is compile time safety and the refactoring I mentioned.

But yes, I am coming around to the notion of just using raw keywords...

Jim

غير مقروءة،
22‏/04‏/2014، 6:36:06 ص22‏/4‏/2014
إلى clo...@googlegroups.com
there is really no reason to use `get-in` with keywords/symbols as they
know how to look themselves up...in other words, you don't need to pay
for any polymorphic calls :

(get-in [:a :b :c :d] someMap) = (-> someMap :a :b :c :d)

Jim

Colin Yates

غير مقروءة،
22‏/04‏/2014، 6:41:28 ص22‏/4‏/2014
إلى clo...@googlegroups.com
Nice.

Alex Miller

غير مقروءة،
22‏/04‏/2014، 11:26:59 ص22‏/4‏/2014
إلى clo...@googlegroups.com
Clojure is designed to make your data accessible generically without getters/setters or other custom APIs so I would encourage direct access via keywords over accessor fns. 

One consequence of this is that fns using a data structure have a direct coupling to the structure of the data. I prefer to see this as (usually) a feature. Accessor functions allow you to create a point of indirection and I have used that occasionally in very narrow circumstances where I did not want to commit to a data structure. However, I think this is the exception rather than the rule. defrecord (or add-ons like Prismatic's schema library) can formalize the contents of your entities and provide documentation and validation where and how you need it.

Colin Yates

غير مقروءة،
22‏/04‏/2014، 11:50:52 ص22‏/4‏/2014
إلى clo...@googlegroups.com
Thanks Alex.

Yep, I think Prismatic's schema is going to be invaluable for making the data structure less opaque and providing the comfort that I have lost from the lack of a rigorous and extensive strict type system (carefully avoiding the use of "strong", "lose", "static" and "dynamic" :)). 

Mars0i

غير مقروءة،
24‏/04‏/2014، 1:48:04 ص24‏/4‏/2014
إلى clo...@googlegroups.com
One of the things I hated about Java when I did Java programming for a living, a number of years ago, was having to define accessors, over, and over, and over again for each class.  What a waste of time!  (Not to mention the instance in which we made a client move to using paper rather than software for three days while I tracked down a null pointer exception resulting from forgetting to modify a name after copying and pasting from another accessor.)  Granted, there are tools that can automate this process (we couldn't afford them then), but why?  Why do you need a special tool just to get the language to do what you're usually going to need, anyway, by default.

Why define an accessor when Clojure has already defined one for you--i.e. the keyword.  (Unless you need it.  I define an accessor when I need two different record types to return the same kind of data even though they don't share the same internal structure.)

mho

Jason Wolfe

غير مقروءة،
24‏/04‏/2014، 3:51:37 ص24‏/4‏/2014
إلى clo...@googlegroups.com
FWIW, internally we use a combination of schema and religious use of letk or safe-get and safe-get-in (from prismatic/plumbing) to pull things out of object-like maps, which together with reasonable test coverage seem to catch almost all of the keyword typos before they become bugs.  The other approach we use in some places is records + java-style field access + warn-on-reflection for compile-time warnings, but we've been doing this a lot less since we've had schemas.  

Mars0i

غير مقروءة،
24‏/04‏/2014، 6:57:16 م24‏/4‏/2014
إلى clo...@googlegroups.com
I do think there's a legitimate role for routine use of accessors in some contexts, btw.  I seem to have been traumatized by my experience with them, however.  :-)

Mimmo Cosenza

غير مقروءة،
25‏/04‏/2014، 7:14:25 ص25‏/4‏/2014
إلى clo...@googlegroups.com
I do as Dan does. Sometimes I prefer to use defrecord instead of a regular map, e.g. when there are mutable values involved. In such a case I always define a constructor for the record instances. 

mimmo
signature.asc
الرد على الكل
رد على الكاتب
إعادة توجيه
0 رسالة جديدة