tag:blogger.com,1999:blog-6204005997345471829.post7327242065062433672..comments2023-03-25T11:24:24.318+00:00Comments on Bad Concurrency: Clojure's Time/Concurrency Model - A Gentle CritiqueMichael Barkerhttp://www.blogger.com/profile/16232688819921959379noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-6204005997345471829.post-21916824488528826452010-11-22T18:17:40.604+00:002010-11-22T18:17:40.604+00:00Try not to think of a reference as a concurrency c...<i>Try not to think of a reference as a concurrency construct, but as a identity ("mutable") construct.</i><br /><br />This is where I think the terms cause confusion. Identity (and entities) are domain modelling concepts, where as immutability/mutability are implementation details.Michael Barkerhttps://www.blogger.com/profile/16232688819921959379noreply@blogger.comtag:blogger.com,1999:blog-6204005997345471829.post-53558410840028830102010-11-21T19:28:03.443+00:002010-11-21T19:28:03.443+00:00"This use of terminology suggests that you im..."This use of terminology suggests that you implement a system that puts every entity behind a reference and while this may sound appealing initially, it has 2 negative effects. Firstly is clutters your domain model with an artificial construct, mixing an infrastructure concern (concurrency) with your domain logic. it is generally accepted that separation of concerns is a good thing, so heavily mixing concerns can be considered as bad."<br /><br />Try not to think of a reference as a concurrency construct, but as a identity ("mutable") construct. That way IMO you can in Clojure explicitly separate immutable and mutable world and you achieve a better separation of concerns as in the traditional approach (separate mutable variables and concurrency artifacts)jozef.wagnerhttps://www.blogger.com/profile/05838644520136642376noreply@blogger.comtag:blogger.com,1999:blog-6204005997345471829.post-60185032018076609522010-11-21T17:09:09.444+00:002010-11-21T17:09:09.444+00:00I think my where my greatest confusion lies is the...I think my where my greatest confusion lies is the the notion that all and only entities have identity and identity is always and only represented using a reference (I am happy to be wrong about this). This was the understanding that I came away with after your presentation (and Rich Hickey's earlier one). As I model my current business domain (financial exchanges) using the Clojure approach, I find myself moving references about based on my concerns around concurrency, consistency & visibility not on my understanding of the business.<br /><br />As I do this, based on my understanding, I am changing the definition of what things are entities. This worries my as I am letting the implementation dictate my model. Like the Smalltalk guys said - "Model First". I found that when (in my head) I broke apart the strong relationship between identity and reference, everything became much simpler. Using a reference to represent an entry point to the model, meant that I could separate out those concurrency concerns from my domain model concerns. At implementation time, simply pick an appropriate aggregate root below which, I want to enforce consistency and apply the reference there. Not worrying about the conflict that my notion of an Entity (defined by DDD) was different to Clojure's notion of an Entity helped. This is why I said that I found the Clojure definitions of Identity and Entities confusing. I think they will also prove confusing to those who already think using Domain Driven Design or come from a heavy data modelling background.<br /><br /><i>How would you solve this problem *without* references and transactions?</i><br /><br />I would still use references (specifically agents with a single writing thread) and like I mention above chose an aggregate root within my model to serve as an entry point.<br /><br />I will do a another post soon focusing on the specifics on the app I'm toying with...<br /><br />Like I mentioned in the blog post, I really like the concurrency model, I find terms screw me up.<br /><br />Couple of other small points:<br /><br /><i>the generic ability to read information is nonexistent in mutable OO languages</i><br /><br />I definitely agree with the mutability part, but OO is neither here not there. I can screw up just as badly using C.<br /><br /><i>we should not be confused by our infrastructure tools, which are perpetually lagging our needs in this regard</i><br /><br />I'm not so sure that we are. I think we are more limited by our own tendency to over-complicate, not clearly model our problems and not really understand how our infrastructure works. E.g. the majority of developers mess up with multi-threaded code because they don't understand how memory works.Michael Barkerhttps://www.blogger.com/profile/16232688819921959379noreply@blogger.comtag:blogger.com,1999:blog-6204005997345471829.post-66842632994203608412010-11-21T16:00:39.465+00:002010-11-21T16:00:39.465+00:00"The second issue is that an operation that s..."The second issue is that an operation that spans multiple entities is difficult to make consistent if all of the entities have individual references. For example, reading threads will be able to see the result of partially applied operations...."<br /><br />Not with Refs, which can only be modified within a transaction. Transactions are atomic. Other threads will never see partially applied operations.<br /><br />http://clojure.org/refsStuart Sierrahttps://www.blogger.com/profile/13693732881629219442noreply@blogger.comtag:blogger.com,1999:blog-6204005997345471829.post-21129505356939992882010-11-21T14:54:57.633+00:002010-11-21T14:54:57.633+00:00Hi Mike,
Your point about reads not being free is...Hi Mike,<br /><br />Your point about reads not being free is fair. I should say that reads are as free as perception can be. That's still a pretty good deal, since the generic ability to read information is nonexistent in mutable OO languages, until you layer in some kind of concurrency protection. But not free. :-)<br /><br />I think you have the separation of concerns argument completely backwards, however. Reference types quite literally separate a concern: identity. I also think that treating concurrency as an infrastructure concern is a mistake. Concurrency is a basic fact of many domains, and we should not be confused by our infrastructure tools, which are perpetually lagging our needs in this regard.<br /><br />You say that an read operation spanning multiple entities is difficult to make consistent if each identity is a reference. I am not sure why this seems difficult--transactions do the bookkeeping, and scoping reads in a transaction is trivial to do. So maybe the better questions is: difficult compared to what? How would you solve this problem *without* references and transactions?Unknownhttps://www.blogger.com/profile/12215509551577051295noreply@blogger.com