AstonJ

AstonJ

Single Responsibility Principle - what does it mean to you and your Elixir apps?

There is a wikipedia definition on this but it doesn’t really cover how you can go further in functional programming. I feel PragDave’s comment (from his course) is better from an Elixir perspective:

I know I’m like a broken record, but I can’t help it. I’m really excited to see how a functional approach makes it so much easier to honor the SRP, both at the function and module level. The fact that state is passed around, and not simply shared, means that functions can and modules can both be split and moved around.

What does the SRP mean to you? How far do you go? How strictly to you adhere to these (or your own) guidelines?

Most Liked

hubertlepicki

hubertlepicki

I have a theory that a lot of these things we learned when doing OOP, no longer make sense when you switch to functional programming. This is precisely because they solve problems that are a result of using Object-Oriented programming in first place.

Take this single responsibility principle for a review, and compare this to how things from standard library work. In either version (one responsibility, one reason to change), this is being broken all the time.

In Elixir & Erlang, modules group together the related functions. That’s it, there’s no big theory behind it. These functions may perform one or multiple things, but as long as it makes sense to keep them in the same module - they are kept there.

sasajuric

sasajuric

Author of Elixir In Action

I personally believe that on some higher-level of thinking many ideas transcend paradigms. In particular, I think that a large module which deals with many things is more problematic to read and understand.

A typical example I see is a case where complex GenServer state is handled directly in the GenServer module. By moving the state manipulation to a separate module, we can separate the domain logic from the time-flow logic, and this allows us to study each aspect of our system in isolation.

For a more concrete example, see my example blackjack code from my To spawn, or not to spawn? article. The domain management is done in separate modules, which means that domain code is not polluted with GenServer and vice versa.

IMO the case for short classes (and also modules and functions) is to allow the reader to understand a single concept without worrying about non-essential details. Being able to understand a domain model without caring how it’s used from the rest of the system simplifies the code analysis, debugging, and extension.

I should also mention that I’m not a purist here. For example, if the process state is simple enough, I just bundle it inside the GenServer. If the model grows, then I split.

But tl;dr I believe that SRP and similar ideas, vague as they are, still apply in FP.

hubertlepicki

hubertlepicki

I think @pragdave might be importing some wisdom from his object-oriented life ;). I was thinking about it when I first opened Elixir’s own source code files, or sources of prominent Elixir libraries like Ecto, and was shocked by the large files containing hundreds of lines of code (+many more lines of documentation). In Erlang they even add a lot of unit tests at the end of the file to keep the tests close to the module they test! (moduledoc in Elixir but more popular I think)

But then, I realized what is a reason for having a short classes and it suddenly made more sense. The reason why we want to keep our classes short and clean is that we can mentally model how instances of this class will behave, and how they will modify the object’s attributes in it’s life cycle. So - we couple state to the functions that operate on this state, and we want this to be as small as possible - otherwise we easily loose track of how this works, and bugs sneak in.

In Elixir, the module has no state. The main reason for keeping classes short does not apply here anymore. Of course, it becomes tiresome to work with files that are thousands lines long, but there is no such thing as internal state of object to be concerned with.

Having said the above: again, the object-oriented wisdom of keeping classes short does have it’s place in Elixir, and again this is when you create processes (GenServer etc). I think it makes total sense to keep them short in terms of lines of code and focused on one thing.

Where Next?

Popular in Discussions Top

laiboonh
Hi all, I am trying to convince my team to use liveview over the current react. What are some of the points where one should consider us...
New
pillaiindu
In django there is a cache framework backed by memcached. Rails also puts a lot of emphasis on caching, and even the idea of russian-doll...
New
fireproofsocks
This is more of a general question, but I’m wondering how other people in the community think about the pattern matching in function sign...
New
praveenperera
How We Replaced React with Phoenix By: Thought Bot
New
AstonJ
I’ve just started the Phoenix part of the utterly brilliant online course by @pragdave. On generating the Phoenix app he uses the --no-ec...
New
restack_oslo
Hello, Please pardon me for any faux paux. I am 46 and this is my first time on a forum of any kind. I wanted to to get answers from tho...
New
chulkilee
Here are the list of HTTP client libraries/wrappers, and some thoughts on HTTP client in general. I’d like to hear from others how they w...
New
tomekowal
Hey guys! I want to create a toy project that shows a chart of temperature over time and updates every 5 seconds. I feel LiveView is per...
New
scouten
I’m looking for a host for the server part of a small (personal) side project that I’m working on. It’s currently written in Node.js and ...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

Other popular topics Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement