It's tricky, but I would ask them what pain points they experience with the Java stack and go from there. I find the biggest barrier is the "yeah, what I've got works fine"/complacency attitude. If they are perfectly happy where they are then great, lesve them to it and go be 10 times more productive ;).
I found clojure a breath of fresh air because it addressed pain I was feeling. There was a cost, of course; everything is a compromise, but my point is to truly "get" Clojure it has to offer you something you consider valuable.
I will say for me, coming from a very deep entrenchment in Spring, Hibernate etc that the biggest struggle I had was undoing years of learning Java EE and all the support that brought with it. The idea of having to think first? Shocker :). I often like to say that the design pattern I use the most now is "Hammock time" :).
There are two bookd you might want to give them, Functional Programing for OO by Brian Marick and another one I can't remember the title of but something like Functional Programming in Clojure and Scala. They might both help provide an on-ramp.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
On Saturday, 11 July, 2015 at 1:24 pm, Johanna Belanger wrote:
On 15 Jul 2015, at 22:14, Johanna Belanger <johanna....@gmail.com> wrote:
Hi Johanna, you may intuit some of my experience by my posts on the DDD groups ;-).
By far the hardest thing I found was applying DDD, identifying bounded contexts etc. However, from a technical point of view the thing that most stood out to me was the power of recording the decision, and effect of every single decision as an event. All mutation is captured in the event log. My ‘aggregate roots’ tend to be a namespace with a multi-method of ‘react-to’ which takes in a command and emits a bunch of events. Those events tend to be trivially mapped to state transitions of the aggregate root. Hydrating the aggregate root then becomes (let [events (event-store/load-for aggregate-id) ar (apply merge events)…]).The strict separation of domain logic/model from the views (and supporting infrastructure) is a significant win; every screen has a server side view with a server side de-normalised store (yeah, OK, a table ;-)). In our domain there are a bunch of different ‘modules’ (I won’t call them BCs!). However, some of our views map across those modules. Imagine I am looking at my current order, I also want to see when it is dispatched from the warehouse or if there is a cheaper deal etc. I also found that many of our existing applications were making key business decisions at the time of querying; what is the sort order for these things, how many things are out of stock etc. It was shocking how many decisions weren’t explicitly in the code/codified in SQL (as a team we are all culpable, but this was written before I got here - ha!).
Putting it succinctly, I found there are many-to-many relationships between modules and views. Modelling this in a ‘traditional’ way would have been a great big ball of mud where one piece of code was concerned with far too many things; there is a significant disconnect between the use cases and the views.From a maintenance point of view - fantastic. ‘How did this get to be this’ is by far the most necessary question our support teams need to answer, now the answer is trivia - all (actually almost all) mutation is done via events - look in the event log. If a view changes then we can simply delete the view and replay all of the events to build the new view.The Clojure tooling needed for this is remarkably small and the conceptual fit is fantastic; immutability - check (event log); data everywhere - yep, events flow through the system; decomplecting everywhere and always - yep, aggregate roots are ignorant of everything apart from their splice of business logic, views are ignorant of everything apart from the screen they support; functional concerns - yep, aggregate roots and views are just reductions of the event log
Pain points:- it is really tempting to share common views/normalise the DB. Do I really de-duplicate the patient name everywhere or have a t_patient table?- having an event store as the SOR changes everything, everywhere, for everyone. Messes with your mind
- DDD is a discipline, not something you can read a book about and do. It is a specialist non-technical skill - getting it wrong can lead to more mess and heartache than the big balls of mud we are at least familiar with
- not much prior art, at least not much published art. Very few general answers; ‘it depends’ is the rote answer
- DDD and event sourcing and CQRS are very different (complementary but different) beasts - tackling all three caused a lot of pain because there is no familiarity anywhere
- performance can suffer, it can also be significantly improved, but my intuition was worth nothing due to the change of paradigms- making decisions when querying actually provides a lot of grace - fix the bug, deploy and the problem goes away. When you have an event log and every decision is explicitly captured you lose that grace. You can add compensating events or (although frowned upon) go through and mutate your events (yeah, I said it was frowned upon). That event log can become a chain around your feet.
- nobody is going to have a clue what you are talking about until you can educate themPlus points:- the words best and most accurate audit log- separation and the fine granularity of models makes parallel development and maintenance significantly simpler
- view models are transient, throw them on different servers to scale - fine- exposes many many key business decisions which weren’t handled explicitly- concepts are a natural fit for the functional world- I am a better developer, engineer and domain expert because of the rigour required
- very little infrastructure required to achieve this- you can view the world as a sequential set of mutations to smaller and more focused state machines- a clear separation of read and write means your write can be more expensive to make your reads more efficient (given that most systems read _far_ more than they write)- being able to restore your system to any moment in time is just fantastic. Opens the door to simulations, replaying history, diagnostics etc.- it tickles your ‘geek’ spot (you know, the one tickled by using Linux instead of Windows, or tiling instead of floating, or being able to use grep, awk and sed together with regular expressions without having to open a book or google)
I haven’t had much experience with Datomic, but I think the event log and Datomic both treat time as an explicit concern and neither are simply plugin replacements for ‘a database’.
I wrote this for a blog post, but I think it is relevant here. After a long comparison of a bit of code, first in Javascript and then in Clojure, I wrote:
At this point, a Javascript developer might say, “You've shown that the Functional style has some advantage, but why should I care? I can write in the Functional style using Javascript. I don't need Clojure.” That is absolutely true, and we all know that developers tend to be fiercely loyal to their languages, up 'til the moment they are not. I myself was fiercely loyal to Ruby, up 'til the moment when I wasn't. True moments of conversion are rare and always depend on a person reaching some point of pain with their current path. I myself suddenly realized that I was working with languages that would not carry me into a future full of multi-CPU computers and massive concurrency ... at which point I began to explore what the future might hold ... at which point I discovered Clojure.
I would, however, counter the Javascript developer with my own set of questions. If you have realized that the Functional style is best, do you want to work in a language that undercuts that style, or supports it? Do you want to burden yourself with the extra discipline needed to pull off the Functional style in a highly mutable language, or do you want to work with a language that was designed from conception to make your life easier ? Do you want to “navigate disappointment” or travel directly in the direction of success?
In his talk, “Why Clojure is my favorite Ruby,” Steven Deobald refers to dealing with pain points in a language as “Navigating disappointment.”