Hi,

2011/8/3 Rickard Lindberg <ricl...@gmail.com>

> Hi,
>
> I am interested in Clojures approach to managing state and its use of
> immutable
> values. I believe immutable values will make the life of programmers easier
> and
> I'm trying to figure out how I can simplify my OO code by using more
> immutable
> values.
>
> In particular, I am wondering how I can model notes that can belong to a
> category.
>
> So a note is a piece of text and a reference to a category. A category is
> just
> a name. However, both notes and categories are entities (the identity is
> *not*
> defined by their value). So it is perfectly ok to have two notes with the
> same
> text and same category, yet they are different notes.
>
> The data structure holding these things together (lets call it NoteDb) has
> a
> list of categories and a list of notes. And I want to be able to say things
> like change the text of a note to this. And when I change the name of a
> category, all notes belonging to that category know that the category name
> has
> changed. I also want to be able to get all notes belonging to a category.
>
> Should I model this as a list of refs? Is there another way to think about
> this
> problem that I don't see because I have mainly done work in OO languages.
>

If indeed for your problem domain, notes and categories can be seen as
entities (e.g. as "entities" are defined in the "Data Driven Design" book),
then you'll either have to use "hard" identities (e.g. an entity = a ref),
or "soft" identities (e.g. an :id property for each entity => note that this
:id will be treated as "opaque" by your algorithms, just assuming they are
values than can be correctly compared for equality, have absolutely no
business meaning -there's no reason for them to change, their value is
somewhat "absolute" wrt to the life of your application's data).
"soft identities" will help not have too many refs, and  also somehow
prepare your app for e.g. database backed long term persistence.
"hard identities" may help fight concurrency access to the global "set of
entities" one will have with soft identities. Indeed, when soft identities
are involved, the set of entities will have to be 'changed' for two reasons
: change of value of a particular entity, or change of value of the set of
entities (added/remove entities). With refs, things can be kept more
separate : a ref for the set of entities refs, and a ref per entity.

So this choice really depends on the effective uses your application(s) will
do with your data.

Going the "soft identity" path is certainly simpler, and allows you to do
things in very elegant and "essential" (as opposed to "accidental", search
Google for "Out of the Tar Pit" essay) ways :

(def notes (ref #{  {:id xxxxx, :text ".....", :category :9999999 }, {:id
.......}, ... }))
(def categories (ref #{ {:id 999999 :name "...."}, ... }))

Try to confine mutation on the external layer of your data manipulation API,
do not intermingle data manipulation and state manipulation, or you'll loose
composability possibilities.

Take a closer look at the clojure.seq namespace, which provides interesting
functions for manipulating, well, data sets !

In Clojure, basically, I think one will avoid the "OOM/Relational Model
impedence mismatch" by design, and see it as a good thing in most cases.

That said, I've not done much database backed applications lately :-D.


You can see from my post that I'm not totally convinced by Jonathan's answer
(and it did not address at all the problem of having several notes with same
value seen as separate entities).

HTH,

-- 
Laurent


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