In the project I've been working on I recently came across a situation where the service was hammered by updates and it started struggling under the load of simultaneous client (predominantly read) requests. The solution was maintain separate thread pools for updates and client requests. The service needs to be available, but we can accept delays in updates. This inspired me to play around with thread pools - which for some reason I've never done before - in a small demonstration.
If you run CommonThreadPoolExperiment you'll see that the number of completed read processes converges to that of the write processes. On my machine, around 10 seconds.
With SeparateThreadPoolsExperiment the numbers are starkly different, the reads are unperturbed by the much slower writes.
Thursday, 1 June 2017
Friday, 17 March 2017
Imitating Scala Futures with Go channels (in Go and Clojure)
Scala's Future abstraction is one of my favourite feature of the language. It's simple, elegant and powerful. I make the beginner's attempt to mimic them in Go in a simplistic domain,
Let's assume we have two functions which will take some time (or http calls that naturally return Futures) and we need to aggregate their results.
The Scala way
The Go way
It's rather clunky compared to Scala's solution. But the main problem is that it's not polymorphic on the types. The same lump of code would need to be redefined every time the function signatures change.
Here is a more generic version below that uses explicit type casting.
Not the nicest code I've ever written. If only Go had generics... Any Golang expert out there who could suggest improvements?
The Clojure Way
Clojure borrowed its go-routine and channels idea from Golang. Yet the difference between the Clojure and Go versions in terms of brevity is striking. It's the result of 3 independent factors. One, Clojure is dynamically typed, hence there is no need to hassle with neither function signatures nor generics, or rather the lack of them. Two, it's a functional language. Maps and list comprehensions are way more terse than Go's for-loops. The third factor is async/go returns a channel containing the result of the function executed. Go needs to create a slice of channels first, loop through the slice of functions, create anonymous functions in go blocks where the function is executed and its result is put on the channel, ....lot's of hassle.
With generics many of Go's problems would go away. Rob Pike explicitly said, no generics, but hopefully someone will just force him or do it himself instead.
Let's assume we have two functions which will take some time (or http calls that naturally return Futures) and we need to aggregate their results.
The Scala way
The Go way
It's rather clunky compared to Scala's solution. But the main problem is that it's not polymorphic on the types. The same lump of code would need to be redefined every time the function signatures change.
Here is a more generic version below that uses explicit type casting.
Not the nicest code I've ever written. If only Go had generics... Any Golang expert out there who could suggest improvements?
The Clojure Way
Clojure borrowed its go-routine and channels idea from Golang. Yet the difference between the Clojure and Go versions in terms of brevity is striking. It's the result of 3 independent factors. One, Clojure is dynamically typed, hence there is no need to hassle with neither function signatures nor generics, or rather the lack of them. Two, it's a functional language. Maps and list comprehensions are way more terse than Go's for-loops. The third factor is async/go returns a channel containing the result of the function executed. Go needs to create a slice of channels first, loop through the slice of functions, create anonymous functions in go blocks where the function is executed and its result is put on the channel, ....lot's of hassle.
With generics many of Go's problems would go away. Rob Pike explicitly said, no generics, but hopefully someone will just force him or do it himself instead.
Monday, 13 March 2017
Solving problems in Scala, Clojure and Go - Template Method Design Pattern
I've planning for ages to write a series of posts about comparing OO and FP solutions for common problems. In a similar vein comparing Scala and Clojure. Usually my enthusiasm doesn't survive until I have time to sit down in front of the computer out of working hours. But recently I've started to read about Go and it rekindled my interest in such mental exercises. It also gives me a nice opportunity to learn Go. Also these 3 languages are quite different, which makes these little problems even more educative.
Without further ado, here is the first one.
In OO polymorphism is achieved by inheritance. Inheritance also enables sharing data and logic sparing the developer some code duplication. It is a powerful tool, but nowadays generally regarded overused. The Template Method Design Pattern is a nice example and I've implemented it dozens (if not hundreds) of times at work. Let's see how to solve the problems it solves in languages that don't have inheritance.
The idea is to devise a toy problem, solve it in Scala (it would be the same in Java, I just want keep the boilerplate down) to demonstrate the OO-way, then come up with Clojure and Go solutions.
The Problem
Our domain has employees who can fall into 2 broad categories, Office Workers and Field Workers. Their base salary and the calculation of how their years at the company contribute to their salary are different. I let the code speak for itself.
Scala/OO solution
Plain and simple for a OO developer.
Clojure solution
No inheritance, obviously and no types either. Therefore the toString and salary functions are not defined on types, but the entity maps are passed as arguments. Another solution could have been using protocols and defrecords, that would have yielded a more OO-like solution. However for a single function it seemed to be an overkill.
Go solution
It took me some time to come up with a solution. I Go there are no abstract classes or virtual methods. This required me to define to a separate employee interface and a baseEmployee struct. And I couldn't attach the salary method to the interface either, even though it has both the yearContribution() and the baseSalary() methods on it. It is not necessarily a problem, this could be idiomatic in Go.
Without further ado, here is the first one.
In OO polymorphism is achieved by inheritance. Inheritance also enables sharing data and logic sparing the developer some code duplication. It is a powerful tool, but nowadays generally regarded overused. The Template Method Design Pattern is a nice example and I've implemented it dozens (if not hundreds) of times at work. Let's see how to solve the problems it solves in languages that don't have inheritance.
The idea is to devise a toy problem, solve it in Scala (it would be the same in Java, I just want keep the boilerplate down) to demonstrate the OO-way, then come up with Clojure and Go solutions.
The Problem
Our domain has employees who can fall into 2 broad categories, Office Workers and Field Workers. Their base salary and the calculation of how their years at the company contribute to their salary are different. I let the code speak for itself.
Scala/OO solution
Plain and simple for a OO developer.
Clojure solution
No inheritance, obviously and no types either. Therefore the toString and salary functions are not defined on types, but the entity maps are passed as arguments. Another solution could have been using protocols and defrecords, that would have yielded a more OO-like solution. However for a single function it seemed to be an overkill.
Go solution
It took me some time to come up with a solution. I Go there are no abstract classes or virtual methods. This required me to define to a separate employee interface and a baseEmployee struct. And I couldn't attach the salary method to the interface either, even though it has both the yearContribution() and the baseSalary() methods on it. It is not necessarily a problem, this could be idiomatic in Go.
Tuesday, 3 January 2017
Solution for "Docker is eating up my disk!"
I've started to play with Docker recently and quickly bumped into a problem. Although I've never experienced it on my Mac, on AWS EC2 the space was eaten up on /dev/xvda1 and killed my Docker process eventually. The solution proved to be running the following commands
docker stop $(docker ps -a -q) || true
docker rm $(docker ps -a -q) || true
docker rmi $(docker images -f "dangling=true" -q) || true
docker volume ls -qf dangling=true | xargs -r docker volume rm
docker stop $(docker ps -a -q) || true
docker rm $(docker ps -a -q) || true
docker rmi $(docker images -f "dangling=true" -q) || true
docker volume ls -qf dangling=true | xargs -r docker volume rm
Labels:
Docker
Saturday, 7 May 2016
New version of Principle
After a year long hiatus, I've touched Principle again. A new version is out, 0.34, that moves all configuration from the clunky pom.xml to a neat yaml file, like the one below
The next big thing will be to make it usable a SBT plugin, while also retaining the Maven plugin nature. By looking at the documentation of "Simple" Build Tool, this looks challenging.
The next big thing will be to make it usable a SBT plugin, while also retaining the Maven plugin nature. By looking at the documentation of "Simple" Build Tool, this looks challenging.
Saturday, 9 April 2016
The Reader Monad
Yet another exploration in Monadland. Like the State Monad, its sibling, Read Monad had managed to elude me until I came across an enlightening example in Debashish Gosh's excellent book, Functional and Reactive Domain Modelling. In the following example I'll describe a simple scenario where I'd usually use dependency injection and refactor it to a Reader monad using variant.
Version 1. Dependency Injection
When one tries to follow FP principles, she strives to build her application up like an onion. The core should contain pure functions, and all interaction with external services - DB, web service calls, user input, ... - , i.e. side-effects, should be confined to the outer layer. In the code above the domain logic and side-effects are undisentanglable. The next version shows an alternative.
Version 2. Higher order function
This is better. `notifyUser` is now a referentially transparent function. The actual execution of the effects is deferred to a later point, when the result function is called with the context. The Reader monad is nothing else just a convenient wrapper around such a function.
Version 3. Reader Monad
The benefit Reader monad offers over the simple HOF-solution is the monadic composability, like in the example below.
Note that inside the for comprehension the context doesn't even appear.
Version 1. Dependency Injection
When one tries to follow FP principles, she strives to build her application up like an onion. The core should contain pure functions, and all interaction with external services - DB, web service calls, user input, ... - , i.e. side-effects, should be confined to the outer layer. In the code above the domain logic and side-effects are undisentanglable. The next version shows an alternative.
Version 2. Higher order function
This is better. `notifyUser` is now a referentially transparent function. The actual execution of the effects is deferred to a later point, when the result function is called with the context. The Reader monad is nothing else just a convenient wrapper around such a function.
Version 3. Reader Monad
The benefit Reader monad offers over the simple HOF-solution is the monadic composability, like in the example below.
Note that inside the for comprehension the context doesn't even appear.
Saturday, 12 March 2016
Struggling with the State Monad
After spending hours trying to find articles explaining the damn thing without resorting to "let's take this contrived example..." or "let's take a real life example, generating pseudo-random numbers" (seriously?!), I'm still left with frustration. Eventually I'd reached out to Kaloz, who pointed me to one of his earlier explorations of the topic. His example is here, but I'm still in the dark why is it any better than a simple foldLeft. In the code below I refactored slightly Kaloz's code to keep the generic part apart from the specific solutions. A second foldLeft-using function is provided to match the signature of the function using the State monad, although I don't see any additional value in that.
Kaloz? What am I missing?
Kaloz? What am I missing?
Saturday, 27 February 2016
What a senior back-end developer should know in 2016
I've been developing software for a decade now and quite often feel overwhelmed by the sheer amount of must-know-s someone needs to possess by common consent to earn the right to be called a professional. I think almost everyone can fail an interview if being asked the wrong questions, regardless of experience.
I've spent half an hour assembling the following lists. I'm too lazy to elaborate the items here (mostly I just mention some related keywords) or structure them properly, but I think the gist comes through. The items also highly vary in importance and required level of depth. Of course it depends on your field, mine is the Enterprise Java (lately Scala) world. E.g. I've never needed to implement a binary tree in my career, but subjectively consider it somewhat "important". I also simply drop in DDD, but it takes years to master (as opposed to getting sufficiently familiar with HTTP).
So, here we go
- Knowing at least one language inside-out
- Good software development principles:
- separation of concerns, polymorphism, SOLID principles, encapsulation, loose coupling, high cohesion
- understanding the concept of good quality code and the capacity to produce it - very vague definition, yet the most important. It has nothing to do with frameworks/technologies/most of the things listed below
- OO fundamentals. Design patterns, SOLID principles
- FP fundamentals - it's just getting into the mainstream, but hopefully sooner or later will be ubiquitous
- Algorithms and data structures ( graph theory, O(n), binary trees, tail recursion, ...)
- Concurrency, thread safety, parallel computation. Deadlock, livelock, threads, thread-pools, locks, synchronization primitives, CSP, Actor model, Dataflow (Functional Reactive Programming)
- JVM memory model
- Monitoring tools (JMX, JProfiler, ...)
- Dynamic vs static typing, pros and cons
- DI frameworks (the concept and at least one, e.g. Spring)
- App servers (like JBoss. The concept at least and pros/cons against lightweight solutions)
- Build tools (Ant, Maven, Sbt, Leiningen, depends on the language)
- Testing
- TDD, BDD, mocks, stubs, load tests, unit testing patterns, integrations tests, acceptance-level tests, non-functional tests, property-based tests, ...
- Databases
- Relational
- Working proficiency with SQL
- Transactions (local vs distributed), ACID, dirty reads, transaction isolation levels, etc
- optimistic/pessimistic locking
- NoSQL - when to use which, pros, cons, etc
- ORM tools
- Middleware
- HTTP protocol
- Network protocols (TCP, UDP, SSL, ...)
- Messaging - Enterprise Integration Patterns, JMS or some alternative, ActiveMQ or some alternative
- REST
- SOAP (not so relevant any more)
- Synchronous vs asynch communication. When to use which, benefits and pitfalls.
- Markup languages - xml, json, yaml, ...
- Small-scale architecture
- packaging, layering principles, cohesion, coupling, static code quality metrics, MVC, UML, Hexagonal Architecture
- Patterns: pipeline, circuit-breaker, ...
- Big-scale architecture
- SOA, microservices vs monoliths
- Scalability (vertical, horizontal, functional decomposition)
- CAP theorem
- Domain-Driven Design
- HTML, DOM, Javascript
- Continuous Integration/Delivery tools
- Deployment tools (Ansible, Capistrano, ...)
- Cloud - e.g. AWS
- Project management methodologies (Scrum, Kanban, ...)
- OSs
- Networks
I'm sure I missed some pretty obvious ones...
Thursday, 10 December 2015
Conway's Game of Life - my take on it in Clojure
If the board is represented as a vector of strings, where a string represents a row. E.g
The solution takes the board and returns the it in the next state.
The solution takes the board and returns the it in the next state.
Friday, 13 November 2015
On Scala
This will be a short one. Having been earning my bread and butter with Scala for 3 months now, I've come to realize: you can write beautiful code with Scala on both small and large scale. It has all the tools you need to do that. The same tools will enable undisciplined developers to make a terrible mess. Thank God we are a small team.
Labels:
Scala
Wednesday, 30 September 2015
OO and FP
Shameless re-post, but great content!
http://somethingdoneright.net/2015/07/30/when-object-orientation-works-a-rule-of-thumb.html
http://somethingdoneright.net/2015/07/30/when-object-orientation-works-a-rule-of-thumb.html
Tuesday, 7 July 2015
My book list
Everyone has to come up with a booklist. That's a fact. This year is the 10th of my professional life and I use the annual to look back over this decade and pick the books that taught or inspired me most. I try to structure the following list respecting chronology (subjective chronology, though - based on when I came across these items), level and theme, sometimes sacrificing one for the the sake of the others.
Head First Design Patterns
An epitome of beginners' books, requiring only basic programming knowledge, funnily written and accessible. Even though Java and OO is not as hip as they used to be, it's a worthy read. Must read even, if you are a young, aspiring Java programmer.
Robert C. Martin: Clean Code
One of my all-time favourites. As much as I dislike Robert C Martin as a speaker - he has apparently irredeemably fallen in love with his own voice - I respect him as a superb writer. Clean Code covers a broad swathe of programming must-knows, its arguments are crystal clear, the style is witty and entertaining. It also introduces, IMHO, one of the greatest practical set of guidelines in programming, the SOLID principles. I think they really capture the essence of good code, and DDD, Hexagonal Architecture, microservices and many other good things can almost completely be derived from them.
Martin Fowler: Refactoring: Improving the Design of Existing Code
Another iconic book. We owe much to Mr Fowler and this book is one of his greatest contributions. Introduced the concept of "refactoring", changing the code in small, controlled steps for the better whilst keeping the functionality intact.
Joshua Block: Effective Java, Second Edition
I don't really know what sets it apart from the first edition, but this is the only way I have seen this referred to. This is a bit more advanced stuff than the previous ones, and more specific to Java. Not too specific, though, to prevent users of other languages to draw some good lessons. Akin to Clean Code, it concentrates on small-scale stuff you meet in your everyday job - builders, classes, exception handling, ... - and does it very well.
Java Concurrency in Practice
You cannot regard yourself a senior Java developer if you haven't read this book. This sounds smug, but has more than a grain of truth. Concurrency is a bit like uncomfortable truth. One usually procrastinate accepting the pain and dealing with it, but if you do that, sooner or later it will come and bite you. The book addresses this difficult and complex topic and does it in a structured and readable style.
Martin Fowler: Patterns of Enterprise Application Architecture
A book targeting the large-scale. It offers a plethora of patterns and time-honoured insights in Fowler's usual engaging style. Very classic.
Martin Fowler: UML Distilled
Far away the days are when we had to generate code from models. Thank God. Although UML has lost much of its charm in the last decade (for the better), it's still a ubiquitous and not-yet-superseded tool in software engineering. Martin Fowler treats it fair in this concise little book, presenting it as a useful tool for thinking and communication between humans as opposed to the "visual programming language" some of its proponents promised it to be and it's failed to live up to.
Michael Feathers: Working Effectively with Legacy Code
This is a truly wonderful book for developers with a couple of years behind their back. Also is one that is a bit too heavy to read from cover to cover in one go, but full of interesting chapters that can stand alone on their own. Although the theme is eponymously about problems and solutions around interacting with legacy code - mostly how one can incrementally carve out chunks of the legacy codebase and plug in something new and well tested in their place -, Mr Feathers offers some very valuable general insights on coding and especially on testing.
Kirk Knoernschild: Java Application Architecture: Modularity Patterns with Examples Using OSGi
The best book I've read about modularity and I have to admit I only skimmed through the second, OSGi-specific part. But the first part about the general principles, challenges and solutions of modularity is awesome. Lots of other books touches this very important topic, but none of them in this depth and clarity.
Robert C. Martin: Agile Software Development, Principles, Patterns, and Practices
This books deserves much more attention than it enjoys. I consider it the big brother of Clean Code, aiming at larger scale problems. Among other things it introduces principles of Package and Component Design, mirroring SOLID principles on a coarser granularity level. Although some static code analyser tools - including my own humble excuse for one, Principle - use some of them to calculate metrics, they are not widely known and appreciated enough.
Steve Freeman, Nat Pryce: Growing Object-Oriented Software Guided by Tests
With so many books and blog posts and rants on TDD it's very hard to imagine that someone can still come up with something fresh and insightful in the topic. Yet Freeman and Pryce delivers that and much more. Through a realistic example they show how to do what the title says and tell a lot about testing and design along the way.
Vaughn Vernon: Implementing Domain-Driven Design
The Red Book. This is a big and heavy volume, full of theory and practical examples, and almost indispensable if you want to grok DDD. Much more down to earth than its predecessor (the Blue Book by Eric Evans). Very-very useful.
Martin Fowler: NoSQL Distilled
Yet another great book of Fowler, exhibiting all the good traits of his other work. Exploring a fundamental topic, engaging style and clarity.
That's it.
What is missing? Probably 1-2 books I forgot, but mostly huge amount of on-line resources. I can't say there is any book about FP that fundamentally influenced me, although FP in general has in the last 2 years. The same could be said specifically about Clojure.
Head First Design Patterns
An epitome of beginners' books, requiring only basic programming knowledge, funnily written and accessible. Even though Java and OO is not as hip as they used to be, it's a worthy read. Must read even, if you are a young, aspiring Java programmer.
Robert C. Martin: Clean Code
One of my all-time favourites. As much as I dislike Robert C Martin as a speaker - he has apparently irredeemably fallen in love with his own voice - I respect him as a superb writer. Clean Code covers a broad swathe of programming must-knows, its arguments are crystal clear, the style is witty and entertaining. It also introduces, IMHO, one of the greatest practical set of guidelines in programming, the SOLID principles. I think they really capture the essence of good code, and DDD, Hexagonal Architecture, microservices and many other good things can almost completely be derived from them.
Martin Fowler: Refactoring: Improving the Design of Existing Code
Another iconic book. We owe much to Mr Fowler and this book is one of his greatest contributions. Introduced the concept of "refactoring", changing the code in small, controlled steps for the better whilst keeping the functionality intact.
Joshua Block: Effective Java, Second Edition
I don't really know what sets it apart from the first edition, but this is the only way I have seen this referred to. This is a bit more advanced stuff than the previous ones, and more specific to Java. Not too specific, though, to prevent users of other languages to draw some good lessons. Akin to Clean Code, it concentrates on small-scale stuff you meet in your everyday job - builders, classes, exception handling, ... - and does it very well.
Java Concurrency in Practice
You cannot regard yourself a senior Java developer if you haven't read this book. This sounds smug, but has more than a grain of truth. Concurrency is a bit like uncomfortable truth. One usually procrastinate accepting the pain and dealing with it, but if you do that, sooner or later it will come and bite you. The book addresses this difficult and complex topic and does it in a structured and readable style.
Martin Fowler: Patterns of Enterprise Application Architecture
A book targeting the large-scale. It offers a plethora of patterns and time-honoured insights in Fowler's usual engaging style. Very classic.
Martin Fowler: UML Distilled
Far away the days are when we had to generate code from models. Thank God. Although UML has lost much of its charm in the last decade (for the better), it's still a ubiquitous and not-yet-superseded tool in software engineering. Martin Fowler treats it fair in this concise little book, presenting it as a useful tool for thinking and communication between humans as opposed to the "visual programming language" some of its proponents promised it to be and it's failed to live up to.
Michael Feathers: Working Effectively with Legacy Code
This is a truly wonderful book for developers with a couple of years behind their back. Also is one that is a bit too heavy to read from cover to cover in one go, but full of interesting chapters that can stand alone on their own. Although the theme is eponymously about problems and solutions around interacting with legacy code - mostly how one can incrementally carve out chunks of the legacy codebase and plug in something new and well tested in their place -, Mr Feathers offers some very valuable general insights on coding and especially on testing.
Kirk Knoernschild: Java Application Architecture: Modularity Patterns with Examples Using OSGi
The best book I've read about modularity and I have to admit I only skimmed through the second, OSGi-specific part. But the first part about the general principles, challenges and solutions of modularity is awesome. Lots of other books touches this very important topic, but none of them in this depth and clarity.
Robert C. Martin: Agile Software Development, Principles, Patterns, and Practices
This books deserves much more attention than it enjoys. I consider it the big brother of Clean Code, aiming at larger scale problems. Among other things it introduces principles of Package and Component Design, mirroring SOLID principles on a coarser granularity level. Although some static code analyser tools - including my own humble excuse for one, Principle - use some of them to calculate metrics, they are not widely known and appreciated enough.
Steve Freeman, Nat Pryce: Growing Object-Oriented Software Guided by Tests
With so many books and blog posts and rants on TDD it's very hard to imagine that someone can still come up with something fresh and insightful in the topic. Yet Freeman and Pryce delivers that and much more. Through a realistic example they show how to do what the title says and tell a lot about testing and design along the way.
Vaughn Vernon: Implementing Domain-Driven Design
The Red Book. This is a big and heavy volume, full of theory and practical examples, and almost indispensable if you want to grok DDD. Much more down to earth than its predecessor (the Blue Book by Eric Evans). Very-very useful.
Martin Fowler: NoSQL Distilled
Yet another great book of Fowler, exhibiting all the good traits of his other work. Exploring a fundamental topic, engaging style and clarity.
That's it.
What is missing? Probably 1-2 books I forgot, but mostly huge amount of on-line resources. I can't say there is any book about FP that fundamentally influenced me, although FP in general has in the last 2 years. The same could be said specifically about Clojure.
Thursday, 7 May 2015
Clojure's Protocol - when to use it?
Coming from an OO-background I instinctively turned to protocols during my early Clojure explorations. Need to model an Aggregate? Complex internal structure, should be hidden, small set of functions operating on it? Protocol, what else?
Eventually I've learnt a bit of FP and started moving towards pure functions, feeling less and less the need to resort to the OO-ish features of the language. However recently I've been spending some time writing a Twitter-reader application and had some trouble with functions with side-effects. Long story short, I've come up with a simple rule of thumb (don't expect anything earth-shattering)
Use protocols when state is involved!
When is 'state' involved?
1. when the program maintains stateful entitites (either in DB or just in memory)
2. communicating with an external system (e.g. Twitter)
The two cases are not that different, actually. If you can abstract away from the communication details, is operating on the DB really much different from operating on Twitter? Twitter could run on your local machine on your DB after all, in theory.
So what's the benefit?
1. you can group functions together. Usually if you manage state, there are multiple operations around it. Save/Delete/Get/Update for DB, StartListeningToStream/StopListeningToStream for Twitter. Having separate methods only grouped by namespace seems somewhat off to me. Maybe a matter of taste.
2. Easier to provide new implementations. You want to replace your Mongo with Reddis, just give a new implementation. I think the cognitive load is much less if all the functions you need to change are bound together by the language itself, so you don't have to hold all those independent functions in your head.
3. Ordinary functions should be pure. If you hide your state behind a protocol, all the rest can be
An example
So the new, all-encompassing, completely universal principle you should absolutely start all your projects with, absolutely without exceptions
1. identify the moving parts in your model
2. hide them behind protocols by having a namespace for each where only the protocol itself and the factory method is public
Still a bit OO-ish? Maybe. But no-one said OO is without merits.
Eventually I've learnt a bit of FP and started moving towards pure functions, feeling less and less the need to resort to the OO-ish features of the language. However recently I've been spending some time writing a Twitter-reader application and had some trouble with functions with side-effects. Long story short, I've come up with a simple rule of thumb (don't expect anything earth-shattering)
Use protocols when state is involved!
When is 'state' involved?
1. when the program maintains stateful entitites (either in DB or just in memory)
2. communicating with an external system (e.g. Twitter)
The two cases are not that different, actually. If you can abstract away from the communication details, is operating on the DB really much different from operating on Twitter? Twitter could run on your local machine on your DB after all, in theory.
So what's the benefit?
1. you can group functions together. Usually if you manage state, there are multiple operations around it. Save/Delete/Get/Update for DB, StartListeningToStream/StopListeningToStream for Twitter. Having separate methods only grouped by namespace seems somewhat off to me. Maybe a matter of taste.
2. Easier to provide new implementations. You want to replace your Mongo with Reddis, just give a new implementation. I think the cognitive load is much less if all the functions you need to change are bound together by the language itself, so you don't have to hold all those independent functions in your head.
3. Ordinary functions should be pure. If you hide your state behind a protocol, all the rest can be
An example
So the new, all-encompassing, completely universal principle you should absolutely start all your projects with, absolutely without exceptions
1. identify the moving parts in your model
2. hide them behind protocols by having a namespace for each where only the protocol itself and the factory method is public
Still a bit OO-ish? Maybe. But no-one said OO is without merits.
Saturday, 18 April 2015
Creating Clojure "actors" with core.async
A plain vanilla "actor" built with core.async. Can wrap any type of logic as long as it can be described with a function with the given - very general - signature.
Labels:
Clojure
,
core.async
Thursday, 16 April 2015
Improving existing code - imaginary checklist - 3
Eliminate cyclic dependencies
Almost forgot about this one, despite being the most obvious (and challenging, possibly).
Decrease ACD (Acyclic Component Dependency)
Related to the previous point, but a quite vague target. I don't know what the proper value is for relative ACD, it possibly depends on the size of the application and other traits of it. STAN is a great tool to help you in that, however.
Almost forgot about this one, despite being the most obvious (and challenging, possibly).
Decrease ACD (Acyclic Component Dependency)
Related to the previous point, but a quite vague target. I don't know what the proper value is for relative ACD, it possibly depends on the size of the application and other traits of it. STAN is a great tool to help you in that, however.
Tuesday, 31 March 2015
Improving existing code - imaginary checklist - 2
Continuing the completely random and unprioritized checklist. Some of them are easy to fix, some are heavy.
Eliminate mutable state where possible
Immutability has many advantages over mutable objects, none of them will I mention here. For an example see the Query class in the previous post. Avoid setters, use final keyword and defensive copies.
Thread safety
Quite self-explanatory.
Separation of concurrency and domain logic
Multi-threading logic should be separated from the rest of the code. It's quite complex on its own, even more when is intertwined with other things.
Invariants and UnitOfWork-s
Check what are the units of work, and what are the invariants. The formers should encapsulate the latter. This is quite an important point. And a not so low hanging fruit, probably.
Push third-party code to the outer layers
This might be a big one. Practically I think almost all application should follow the Hexagonal Architecture style. This can be achieved iteratively, but could take a long time to get there if the code hasn't been written that way.
To be continued...
Eliminate mutable state where possible
Immutability has many advantages over mutable objects, none of them will I mention here. For an example see the Query class in the previous post. Avoid setters, use final keyword and defensive copies.
Thread safety
Quite self-explanatory.
Separation of concurrency and domain logic
Multi-threading logic should be separated from the rest of the code. It's quite complex on its own, even more when is intertwined with other things.
Invariants and UnitOfWork-s
Check what are the units of work, and what are the invariants. The formers should encapsulate the latter. This is quite an important point. And a not so low hanging fruit, probably.
Push third-party code to the outer layers
This might be a big one. Practically I think almost all application should follow the Hexagonal Architecture style. This can be achieved iteratively, but could take a long time to get there if the code hasn't been written that way.
To be continued...
Binary Tree implementation in Haskell, Clojure and Scala - 2
And thanks to @Kaloz, here is the Scala implementation with a slightly altered/extended functionality.
Improving existing code - imaginary checklist - 1
I endeavour to prepare a checklist I would go through if I had to start to work on a brownfield project. Small things to improve, hunt for the low hanging fruits. Don't expect any enlightenment here, these are just pearls of blue-collar wisdom.
Handling unrecoverable exceptions
In my current project we use messaging via ActiveMQ. Should an exception occur, the message is bounced back to the queue, then retried. It's fine, as long as there is a chance of recovery and sometimes - for example when the message is invalid in some way - there is none. In this case bouncing the message back is a waste of time and resource, plus the message can and up in the Dead Letter Queue leading to memory loss. So instead we should catch these exceptions as close to the entry point as possible and simply log them.
Validating input
Related to the previous point. To adhere the fail-fast principle, the inputs of the system should be validated. Validation is usually against some domain criteria, so I would put the logic in the Domain layer, just as the input passed the ACL. Should the input fail to comply, throw an unrecoverable exception.
Validate domain objects
I wouldn't stop at the inputs. I'd validate every domain object upon creation. Design by contract is a very good practice.
The validation should throw an unrecoverable exception. See the first point.
To be continued...
Handling unrecoverable exceptions
In my current project we use messaging via ActiveMQ. Should an exception occur, the message is bounced back to the queue, then retried. It's fine, as long as there is a chance of recovery and sometimes - for example when the message is invalid in some way - there is none. In this case bouncing the message back is a waste of time and resource, plus the message can and up in the Dead Letter Queue leading to memory loss. So instead we should catch these exceptions as close to the entry point as possible and simply log them.
Validating input
Related to the previous point. To adhere the fail-fast principle, the inputs of the system should be validated. Validation is usually against some domain criteria, so I would put the logic in the Domain layer, just as the input passed the ACL. Should the input fail to comply, throw an unrecoverable exception.
Validate domain objects
I wouldn't stop at the inputs. I'd validate every domain object upon creation. Design by contract is a very good practice.
The validation should throw an unrecoverable exception. See the first point.
To be continued...
Tuesday, 24 March 2015
Binary Tree implementation in Haskell, Clojure and Scala
I've embarked on learning Haskell recently. I only start to suspect the power of this language, but I'm already impressed with its beautifully succinct and readable, no-nonsense syntax. Nuff' said, let's do a demonstration!
Haskell
Clojure
Scala - I've failed with this one. Maybe @Kaloz can help me out.
Haskell
Clojure
Scala - I've failed with this one. Maybe @Kaloz can help me out.
Thursday, 27 November 2014
Swarm - I
I've read a lot of interesting stuff about swarm-intelligence and a couple of weeks ago the idea suddenly came to implement something in Clojure. The full source code is in Github (the application can be run from the app.clj), here I'd like to show how the story has evolved step by step. The first part of the task was to implement some kind of "vector algebra" to model the moves of entities.
Subscribe to:
Posts
(
Atom
)