[erlang-questions] Using processes to implement business logic
Fri Jan 30 15:45:24 CET 2015
On Fri, Jan 30, 2015 at 4:52 AM, Camille Troillard <lists@REDACTED> wrote:
> I am looking for opinions about using processes to encapsulate the state of business entities.
By using the term "business entity" you've tipped your hand I'm afraid :)
It's hard, and not productive in my experience, to map RDBMS and/or OO
modeling concepts into Erlang. People do it, try it, etc. - but I just
don't think it's a good fit.
If you can forget about "state" and "models" - frankly forget about
any "big picture" "paradigm" for "architecting" - and instead just
pick one problem you have to solve, and dive in and solve it, you
might not miss any other the other stuff.
> It looks like, in the context of our problem, we should have more advantages implementing our domain model using processes rather than simple Erlang records. It also appears that processes will act as a nice cache layer in front of the persistent storage.
This is a very common method for software construction:
Step 1 - Define your domain model - so you starting naming things,
classifying them, specifying how they relate to one another - this is
what taxonomists do - it's what Adam did.
Step 2 - Add behavior to your model - so convert the abstract
definition into classes, or into schema with triggers, etc.
Step 3 - Optionally add a UI layer, complete with its own domain model
This can work - but for me it feels very old timey - back when apps
just sat atop a a huge RDBMS. I guess you do still see it in OO camps
- I was looking at a Ruby app the other day - and sure enough there
was a separate directory containing "domain model" type stuff.
> So, what are your experiences?
I'd drive your original question far far out of my mind and press on
with a laser focused problem definition that's scoped tightly enough
that you could possibly solve it in 2 - 3 days. It should be related
to your business, assuming that what the original "business entities"
Here's what Erlang will offer...
You'll get functions, which let you create APIs. A so-called business
entity might manifest itself this way:
> User = myapp_user:new("Jim").
What is User here? Is it a record? Is it a map? Is it a proplist? Is
it a reference? Is it a...
It doesn't matter. It's a user. The point is that you get a new user
by calling that function. There's no state model here.
What about user attributes? Functions...
> "Jim" = myapp_user:get_name(User).
> AnotherUser = myapp_user:set_name(User, "Jenny").
No model. Just an API.
If you're concerned about implementation at this point, that's okay.
How would you implement this API? I don't know - use a map as the data
structure. I don't personally care - you don't have to care. Early on
it probably doesn't matter. Performance, memory, etc. is the least of
your concerns starting out. Just get some first-pass solution to your
problem working. See it work. See it fail. Then fix it, with the
benefit of an actual failure.
Erlang also gives you processes.
I would not think of a process as an encapsulator of a "business
entity". Actually, I wouldn't use this term, ever again, in my life.
(I'll use it here, but only a few more times.)
A process is an independent thread of execution. So if you have any
sort of independent activity in your app, you'll need processes. You
in fact might not. If you're building a web app, processes and their
lifecycle are handled by the web server - you'll just feed it
functions. Where are the business entities here? Don't look for them.
Just think about what your application should *do* - then build that
using functions. Processes will call those functions in time and
That's an app in Erlang.
> Now another question... given this “actor” based approach, I am having difficulties to figure out a proper way of dealing with processes lifetime. How would you do this in practice? Manually, or implement simple garbage collection, reference counting, ...?
Sticking with "user" as our business entity (sigh) what's its
lifetime? Unless you are building a simulator where users come and go
quickly, we're certainly not talking about representing a user with a
process. For me it's very hard to even think of a "user" as existing
at all in a typical businessy app. You have "user state" - and that
will be initially created by some *activity* or trigger - e.g. some
HTTP request from a web app (someone clicked "Create User" on a web
form). Then some other event comes along - maybe a timed cron job -
and it checks some state of a "user" and performs some work. Or
someone requests a web page and you have to read user state. It's all
activities here (processes) and logic (functions).
I wish I had a programming model word I could just use here - like
"Object Oriented" or "Domain Driven Design" - and then it'd all just
fall into place. I think this is "Like the way you'd program in C, but
with rich process semantics". LTWYPICWRPS does not roll off the
I personally use "Process Oriented Programming" but it's not used
often here. I'd like to see more use of it - I think it's a useful
mental model for building apps in Erlang.
The opening is a good summary of an Erlang app:
| Process-oriented programming is a programming paradigm
| that separates the concerns of data structures and the concurrent
| processes that act upon them.
I'd like to add something about functions here, but then this leaks
into FP land. That's fine, but it might dilute the model. Smarter
people than me will have to help here.
Other parts of the article don't apply well - e.g. Erlang is certainly
not limited to working with data structures that are "typically
persistent, complex, and large scale".
The real problem though is when you try to read up on this topic:
This is utterly tragic - as, at least in my extremely humbly modest
opinion, this *is the way* to think of and build software.
> erlang-questions mailing list
More information about the erlang-questions