I am experimenting with different ways of writing Elixir software, and writing down some guiding principles for myself. One of the things on my list that I am experimenting with is not worrying about concurrency / process / OTP at the beginning.
So my question is, how hard is it to add supervisors, workers, etc. after the fact? Is it a mistake not to think about this upfront?
(I mean, if all I worried about what concurrency, not the supervision part of things, I would be easy to inject spawning a new function to do some work into already existing system).
Depends what you are building. If you’re building a web app with Phoenix then I think that approach is perfectly fine. Keep it simple.
It’s easy enough to refactor later if you want to optimize more.
Hi @brightball. That’s a tough one to answer. I do use Phoenix, but it’s simply a web front end to the rest of my app, which is an umbrella. I have it set up like acme bank. Sorry I’m on mobile so can’t find the link.
Especially in the beginning you have to be careful that you do not try to consider too many things all at once because you’ll be heading straight for analysis paralysis.
Also consider that according to Francesco Cesarini (of Erlang Solutions) it is not that uncommon for someone with 10 years of mainstream development experience to take an average of 6 months of full time commitment to become proficient in programming Erlang while moving past the hurdles of:
- Using pattern matching instead of conditionals
- Using recursion instead of iteration
- Thinking concurrently
i.e. exactly the type of hurdles that one faces when using Elixir competently.
Cesarini also makes a distinction between programmers and application architects - essentially a programmer needs additional experience and practice to rise to the responsibility of structuring an OTP application and it’s supervision tree.
- So first just solve the problem in the way you have always done. This is necessary to simply develop a better, possibly more intuitive sense of the problem that you are currently dealing with. Attack it with sequential programming - it may be necessary to actually implement a sequential solution just to sufficiently understand the problem.
- Once you have a “more intuitive sense of your problem” it’s time to step back and look at how the various parts of your problem and solution depend on one another and evaluate which dependencies are accidental and which are essential - by eliminating accidental dependencies you will start to uncover opportunities for concurrency.
- Dealing with OTP there is also the challenge of selecting the right pattern that provides the generic functionality that you need implement the specific logic for. So I think it’s essential to spend some time with the various behaviours away from any particular problem that you may be trying to solve - just to get a better feeling for what the behaviour was created for and what it can do for you.
So in the beginning exploring concurrency is pretty much a separate activity - however later with more practice and experience you’ll able to recognize opportunities for concurrency earlier and earlier in the development process.
@peerreynders I am very grateful for your thoughtful answer. The whole analysis paralysis problem is a trap that I fall under often - and in general, not just when it comes to programming. I like to think of myself as competent when it comes to
recursion, etc, but I admin I’m a novice when it comes to concurrency. At any rate, your advice is top-notch and has spurred me to go forth with what I do know, and worry about how to make it better, more idiomatic, afterwards.