Domain Modelling

42 views
Skip to first unread message

Barry Dahlberg

unread,
Jan 24, 2010, 4:29:25 AM1/24/10
to Clojure
Hi, I'm an experienced C# / .Net developer and a relative Lisp newbie.

In my .Net programming I have taken a lot of design inspiration Domain
Driven Design and Eric Evans book in particular. The idea that a
developing a strong model of the problem domain is the most important
part of application design sits well with me.

It is obvious (to me) how to go about this in C#... a class for
Product, properties for Name, Price etc. Where should I go for advice
on how to model these ideas in Clojure?

As is typically the case with introductory material, the examples I'm
finding mostly deal with small problems which are solved with simple
lists and maps. This is fine for learning syntax and API but it's
hard to see how this scales to a meaningful application.

To give you an idea of where I'm coming from, my current work project
involves a database of around 120 tables and is exposed as a B2B web
site and several desktop applications. This isn't huge, but its big
enough that managing complexity becomes very important.

An open source Clojure project might make for good reading, are there
any out there that are end products rather than frameworks?

Cheers
Barry the Unenlightened

Stuart Sierra

unread,
Jan 25, 2010, 12:30:39 PM1/25/10
to Clojure
On Jan 24, 4:29 am, Barry Dahlberg <barry.dahlb...@gmail.com> wrote:
> It is obvious (to me) how to go about this in C#...  a class for
> Product, properties for Name, Price etc.  Where should I go for advice
> on how to model these ideas in Clojure?

It's basically the same thing. Use namespaces instead of classes and
functions instead of methods.

You can use the same techniques -- encapsulation, abstract data types,
polymorphism -- that you would use in object-oriented programming.

Though only available on github right now, datatypes and protocols
will provide a very flexible, efficient data modeling scheme.

-SS

Roman Roelofsen

unread,
Jan 25, 2010, 1:20:50 PM1/25/10
to clo...@googlegroups.com
2010/1/25 Stuart Sierra <the.stua...@gmail.com>:

> On Jan 24, 4:29 am, Barry Dahlberg <barry.dahlb...@gmail.com> wrote:
>> It is obvious (to me) how to go about this in C#...  a class for
>> Product, properties for Name, Price etc.  Where should I go for advice
>> on how to model these ideas in Clojure?

First, I also like DDD and think that it is a very good approach.

When I first came to Clojure I also tried to map everything to maps
(counterpart of objects), hierarchies, relationships, etc. This design
was the natural mechanism in my previous programming languages to
express everything. After a while I noticed that this is probably not
always the best way to define the domain in Clojure. Why should
objects + hierarchies be the "only true thing"?

After playing around with clojureql I noticed how well the relational
data model maps to a functional language. Processing lists (result
sets), joining, filter, group by, etc. are ideas I found in both
worlds. I am currently working on a toy project where I "declared" the
relational model as my dominant way to express data, persistent as
well as in-memory. So far I can say that it is working seamlessly.
Everything feels natural. The relational model is very well understood
and it was quite easy for me think in this model during coding as
well. Also, I was quite happy that I did not need to work with deep
hierarchies, etc. in a dynamic language anymore. Using the relational
model also gave me the SQL-DDL as an expressive way to define my data
schemes, types, etc.

Cheers,

Roman

wlr

unread,
Jan 25, 2010, 4:06:02 PM1/25/10
to Clojure
> When I first came to Clojure I also tried to map everything to maps
> (counterpart of objects), hierarchies, relationships, etc. This design
> was the natural mechanism in my previous programming languages to
> express everything. After a while I noticed that this is probably not
> always the best way to define the domain in Clojure. Why should
> objects + hierarchies be the "only true thing"?
>
> After playing around with clojureql I noticed how well the relational
> data model maps to a functional language. Processing lists (result
> sets), joining, filter, group by, etc. are ideas I found in both
> worlds. I am currently working on a toy project where I "declared" the
> relational model as my dominant way to express data, persistent as
> well as in-memory. So far I can say that it is working seamlessly.
> Everything feels natural. The relational model is very well understood
> and it was quite easy for me think in this model during coding as
> well. Also, I was quite happy that I did not need to work with deep
> hierarchies, etc. in a dynamic language anymore. Using the relational
> model also gave me the SQL-DDL as an expressive way to define my data
> schemes, types, etc.

A relevant paper Rich brought to the attention of the Clojure
community is:

http://web.mac.com/ben_moseley/frp/paper-v1_01.pdf

Barry Dahlberg

unread,
Jan 25, 2010, 9:08:59 PM1/25/10
to Clojure
Thanks for the thoughts everyone, I'm having a read through that paper
now. I'm still looking for some code to read because while what you
are saying makes, I've done so much OOP my brain is having a hard time
making the jump.

Also added it as an suggestion in this thread if anyone else is
interested and wants to vote it up:

http://www.reddit.com/r/Clojure/comments/atzz7/full_disclojure_i_need_topics/c0jeke6

Cheers
Barry

pmf

unread,
Jan 26, 2010, 2:46:51 AM1/26/10
to Clojure
On Jan 25, 7:20 pm, Roman Roelofsen <roman.roelof...@googlemail.com>
wrote:

> After playing around with clojureql I noticed how well the relational
> data model maps to a functional language. Processing lists (result
> sets), joining, filter, group by, etc. are ideas I found in both
> worlds. I am currently working on a toy project where I "declared" the
> relational model as my dominant way to express data, persistent as
> well as in-memory. So far I can say that it is working seamlessly.
> Everything feels natural. The relational model is very well understood
> and it was quite easy for me think in this model during coding as
> well. Also, I was quite happy that I did not need to work with deep
> hierarchies, etc. in a dynamic language anymore. Using the relational
> model also gave me the SQL-DDL as an expressive way to define my data
> schemes, types, etc.

Do you plan on setting this up somewhere? I'd be very interested to
see this, but it does not seem to be amongst your github-stuff.

PublicFarley

unread,
Jan 25, 2010, 1:01:15 PM1/25/10
to Clojure
Stuart pretty much nails it. This is the strategy that I have taken in
my own Clojure apps. Having said that it would be nice to see an
extensive, with comprehensive examples, "Domain Modelling with
Clojure" write up.

On Jan 25, 12:30 pm, Stuart Sierra <the.stuart.sie...@gmail.com>
wrote:

Barry Dahlberg

unread,
Jan 31, 2010, 10:33:59 PM1/31/10
to Clojure
Perhaps I'll write up my findings once the language stops intimidating
me.

At the moment I'm writing an account "object". I have some standard
CRUD type functions which operate on a map behind the scenes. I would
like to add some metadata to start specifying rules for validation, UI
generation and so on. The trouble is I can't really figure out where
to attach this metadata as I don't have a type definition as such,
e.g. I would do this in C#:

[Required, MaxLength(50)]
public string Name { get; set; }

defstruct seems promising though I can't find an example with
metadata.

Any pointers of where to start looking?

Cheers
Barry

Erik Price

unread,
Feb 1, 2010, 6:53:34 AM2/1/10
to clo...@googlegroups.com
On Sun, Jan 31, 2010 at 10:33 PM, Barry Dahlberg
<barry.d...@gmail.com> wrote:
> Perhaps I'll write up my findings once the language stops intimidating
> me.
>
> At the moment I'm writing an account "object".  I have some standard
> CRUD type functions which operate on a map behind the scenes.  I would
> like to add some metadata to start specifying rules for validation, UI
> generation and so on.  The trouble is I can't really figure out where
> to attach this metadata as I don't have a type definition as such,
> e.g. I would do this in C#:
>
>    [Required, MaxLength(50)]
>    public string Name { get; set; }
>
> defstruct seems promising though I can't find an example with
> metadata.
>
> Any pointers of where to start looking?

You can attach metadata to Clojure constructs using the with-meta function:

user=> (def x {:name "Frank"})
#'user/x
user=> (def x-with-metadata (with-meta x {:RequiredParameter true,
:MaxLength 50}))
#'user/x-with-metadata
user=> (:MaxLength (meta x-with-metadata))
50

As for whether you want to define the metadata directly on your map,
or on functions that construct/operate on your map, or somewhere else,
that's your design decision.

e

Barry Dahlberg

unread,
Feb 1, 2010, 4:24:31 PM2/1/10
to Clojure
I wrote something like this last night:

(def user-metadata {:fields
((:name (required) (max-length 50))
(:email (required) (max-length 250)))})

(defn create-user [name, email]
(with-meta
{:name name :email email}
user-data))

I have a validate function which pulls the metadata from a given
instance and I can also access user-metadata directly for generating
UI forms and so on. The required and max-length functions each
generate little validators which have a predicate, error message
formatter etc.

Is this sensible Clojure?

Cheers
Barry

Am

Reply all
Reply to author
Forward
0 new messages