Laurent PETIT wrote:
> While interesting, this approach seems to me limited to simple cases :
>  * limited in possibilities: you are not able to directly use values of 
> other fields. So in more complex cases, you won't be able to combine 
> calculated values without code repetition or prepraration via lets ..
>  * limited in extensibility: in a live system, you won't be able to 
> change the function that displays a name because it's "hard-coded" once 
> and for all at the same time the data is entered in the system. 
> Depending on your use cases, it may or may not be a problem, though.
>  * limited for persistence: when you want to persist a lazy-struct-map, 
> the computed value is fixed and stored, where it should not be used I think.
>  * limited for equality tests (in relation with "limited in 
> extensibility"): you will not be able to succesfully compare for 
> equality 2 persons with the exact same essential data, if the way to 
> represent names has been even slightly enhanced, since the :name value 
> will always be used for the comparison as well. So it's not just a 
> problem for performance (very minor in that case, though it may not be 
> that minor in other cases), but also a problem of correctness, in the 
> long run (for systems you want to keep "live", and without having to do 
> weird things when you have to marshall / unmarshall your data).

Thanks for your insightful reply, Laurent. You are right, lazyseq is
indeed too limited to be used in the way I proposed. It's still very
cool, though, and I'm sure I'll find some other use for it :)

> I would like to offer another possibility. Not ideal, maybe, but that 
> may answer your needs.
> Basically, the idea is that with a language like clojure that has higher 
> order functions and macros, writing "boiler plate" code should be a code 
> smell. The good news being that in Java, this "boiler plate" code smell 
> has no solution in some cases (think about design patterns), while with 
> a lisp, you can do something for that.
> 
> By using a macro, you could generate "boiler plate" getters for your 
> structure. And just "override" with new definitions those getter/setters 
> that need computations.

The thing that bothers me is that AFAIK there's no standard macro to do
this in Clojure. Combined with the facts that spelling out each accessor
by hand would be a code smell, and all APIs -- internal or external --
need some form of information hiding to remain stable, I'm left feeling
that information hiding should be done in some other way in Clojure.
That's why I asked for the idiomatic way to solve the problem in my
example. One can write FORTRAN in any language, and I could write any
language in Clojure, but I'd rather learn Clojure :)

Another issue I have with the accessor function approach is that it can
be circumvented very easily by accident because the data structure is
exposed to the users of the API. All it takes is typing (:first-name
some-person) instead of (first-name some-person), and you get a map
lookup instead of a call to a getter. Both forms work as long as the
records are maps containing the key :first-name, but the former breaks
when the data structure changes. This is especially problematic when
wrapping an existing map with accessors -- how can you be sure that you
converted each and every key lookup to a getter call?

The standard OO approach to information hiding would be private fields
and accessor methods. Any suggestions for the One True Clojure Pattern
that addresses the same problem?

Now that I've read Programming Clojure I know the capabilities of the
language. My problem is that I have no idea how to apply them to solve
real-world problems, such as the contrived example in my first message.
I hope Mr. Halloway starts writing the sequel soon :)

--
Timo

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