kecatan914

kecatan914

What is your opinion on effect handlers or the lack of in Elixir?

I’m studying more and more functional programming and Elixir is the language I liked the most. I would like to have static types, but I can leave without it. The biggest issue so far has been the fact that state can happen absolutely everywhere. Isn’t this a huge drawback in terms of reasoning and referencial transparency?

Most Liked

sodapopcan

sodapopcan

As many of us like to talk about, Erlang is not an academic language and is only functional because it needed to be. Many of us like to say “pragmatic” :slight_smile: So it doesn’t come with a lot of things that other functional languages have and it’s up to you do the right thing. Effectful functions will almost always (or, in the standard library I believe always) return a status tuple—usually {:ok, _}/{:error, _} which another user around here has affectionately referred to as a ghetto monad :smiley:) or have a ! at the end of its name which signals that it will raise in case of an error. But ya, there is no way to enforce this at compilation, unfortunately. It can definitely be a problem if you’re working with people who don’t know what they are doing. Usually we try and keep side effects at the same “layer” and something like boundary can help with this. It still won’t stop someone from calling File.write buried away in some poorly named private function but you can, for example, reasonably keep something like database interactions in check.

Another option is fairly new library called Efx. It’s primary purpose is for mocks but it requires that you define any function that needs to be mocked with defeffect. As it turns out, you could use defeffect for all effectful functions, even if you aren’t going to mock them. But again, this isn’t something enforced by the compiler.

As a positive, from a pure base language syntax point of view, Elixir is always immutable. We don’t any keywords to make a variable mutable. If we want state, we have to start a server! Or use the built in key/value store or some other such solution that isn’t as assigning a variable.

TL;DR, if you are comfortable with FP, it’s not really a problem. But ya, I do have first hand experience of it becoming a problem.

derek-zhou

derek-zhou

I think what you meant to say is side-effect can happen absolutely everywhere. State management is actually a strong suit for Elixir/Erlang.

Yes, Elixir and Erlang are not pure. It is a trade-off that the language designer carefully made. There are also Closure, Ocaml and Scala in different places on the pure-ness spectrum; try them and see how you like the trade-off they made.

garrison

garrison

Every function is referentially transparent if you’re brave enough!

In practice most of us are writing webapps where we hit a DB for our state anyway. Honestly other than that I very rarely write functions that aren’t pure.

It can happen, but in practice it rarely does. Have you actually run into problems here or is this more on the theory-crafting side?

Off the top of my head the only common examples of mutable state that I actually run into are:

  • :rand.seed/2
  • Plug CSRF protection stores the token in the process dictionary
  • Ecto transaction state (in a transaction or not) is implicit

And all of these are pretty valid reasons to abuse mutability IMO. There are certain (rare) situations where immutable functions are actually less safe because it would be easy to forget to pass something in. For example, one might forget to pass a seed to Enum.random() if it worked that way, causing subtle bugs. Likewise with the CSRF token, where such a mistake could be a serious vulnerability.

joelpaulkoch

joelpaulkoch

The other thing you have to consider is that other functional programming languages handle effects with types because they can fail and the type forces you to handle the error case.

As others have said in Elixir that’s commonly handled with ok/error tuples but not enforced in any sense.
However, I’d say that the runtime mitigates the problem as we’re working with supervised processes that isolate errors and can be restarted when they fail for unexpected reasons.

So it’s basically, you should handle error cases but it’s not enforced. If you forgot something or there is something really really unexpected happening, it won’t crash everything else and you can fix it the next day.

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
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
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
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
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
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement