Hi,

To contrast our experiences of the language and the different approaches to
deal with some problems:

On Sun, Jun 10, 2012 at 4:47 AM, Kurt Harriger <kurtharri...@gmail.com>wrote:

>  Many will say that side-effecting functions are more difficult to test
> then pure functions... However after writing about 4000 lines of clojure
> code, I realized that things in practice are never quite as simple as they
> seem.  As functions are composed the data structures they work with grow
> larger and more complex and this leads to maps containing maps containing
> lists containing maps and a minor change downstream can ripple through the
> program.  Tests become significantly more complex and fragile as the input
> and output structures grow in complexity.
>

Do you test only the functions or do you have also introduced "lint"
functions which check the shape of your data. To me, these are pretty
useful: you can use them in tests, pre/postconds, middlewares to guard
against untrusted sources etc.



> This reminded me of another OO code smell.... "Don't talk to strangers"
> and the Law of Demeter, instead sending and returning maps of lists of maps
> I started returning maps of functions.  This provided additional decoupling
> that enabled me to refactor a bit more easily additionally maps of maps of
> lists of maps often need to be fully computed where as a map containing
> functions allows me to defer computation until it is actually required
> which may in many cases be never.
>

Basically you are returning a "lazy map" a map of keys to delayed values
(why not use delays instead of fns as values?), while it is sometimes a
necessity to do so, the implied trade-off must not be overlooked: the map
can't be treated as a value anymore: if you call twice the pure function
which generates such a lazy map twice with the same arguments, you get two
lazy maps which are not equals! I'm not even speaking about being equal to
their non-lazy counterparts (which makes them a bit harder to test)


> Although very idiomatic to use keywords to get from maps, I have started
> to think of this as a code smell and instead prefer to (def value :value)
> and use this var instead of the keyword because it allows me to later
> replace the implementation or rename properties if it is necessary to
> refactor and I want to minimize changes to existing code or make changes to
> the existing code in small incremental units rather than all at once.
>

I think this is a premature optimization. If you need to get rid off
keywords acces later on, you can either do what you propose and modify all
the call sites to remove the colon (but the important thing is that it
won't change the shape of your code, it's a minor refactoring) OR if you
are really stuck and don't want to touch the codebase, don't forget that in
Clojure (unless you are using interop) you are always one abstraction away:
you can define your own associative type which will knows how to respond to
lookup for gets. Plus doing so you may even choose to leverage the
optimized code path for keyword lookups (see IKeywordLookup.java).

Christophe

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

Reply via email to