What do you prefer to use for type checking Elixir/Erlang code? (poll)

The poll allows up to 2 votes for cases where people have a preferred tool for Elixir and a separate preferred tool for Erlang or they simply can’t choose a favorite. :smile:

1 Like

Some followup up questions/discussion:

2 Likes

Related poll for those interested…

:023:

1 Like

If you don’t use any form of type checking tool, do you still bother maintaining typespecs?

Yes, althought I’m sorta bipolar about this. On the one hand, they really help as docs. On the other hand, at times writing them, while knowing that they ultimately mean nothing as they aren’t enforced, feels rather pointless.

1 Like

I always try to use Dialyzer and typespecs as much as possible. Even for project where I don’t use Dialyzer, typespecs are used.

At work, Dialyzer warning are tracked by our CI-tool. Builds don’t fail when introducing Dialyzer warnings, but there is a strict agreement om fixing those warnings as quick as possible.

I have tried several of the other tools, but they simply don’t work on our code base - they usually crash in one way or another.
Would love some faster and more accurate type analyser tools, but for now Dialyzer works and does indeed find potential issues.

5 Likes

Checking out if I can use https://gleam.run for most of my code and just have the necessary parts like Phoenix and Ecto in Elixir.

7 Likes

We use Dialyzer and CI fails if there are any warnings. Also, we recently enabled the unmatched_returns flag, which I can recommend.

Regarding other tools, I thought about trying TypeCheck and enabling it in tests. Given good coverage, I’d expect it to be quite accurate.

3 Likes

There also was GitHub - Comcast/dialyzex: A Mix task for type-checking your Elixir project with dialyzer which for me was more pleasant to use than Dialyxir, but it seems to be dead.

1 Like

I have also considered doing that, but haven’t had the time to look into it properly.
So if you can share anything about how this works out for you, I would be really interested!

1 Like

I will! Currently I’m writing a little code generation thing so that I can read Ecto schema structs in a type safe way in Gleam (I’m calling it Neglecto). But I’ll post a separate thread about it if it goes somewhere. :slight_smile:

5 Likes

With regards to alternative BEAM languages, I’m currently learning Purerl, which is Purescript with Erlang as the backend. The interop story is very good: running PS code from Elixir is very easy, and FFI in Purescript seems to also be frictionless. They also have OTP, Gun, etc bindings. However, I can see why it didn’t get more traction: I’ve been studying it for a couple weeks, I’ve writtern monad transformers but I still don’t know how to make a simple GET request :slight_smile: . But, it’s fun and powerful, so I’m looking forward to learn it and eventually use it with my Elixir code.

6 Likes

but I still don’t know how to make a simple GET request

reminds me of “Hitler reacts to functional programming” video (:slight_smile:

3 Likes

I use whatever the ElixirLS extension for VS Code uses… I don’t know what that is! I think it’s plain Dialyzer?

I forgot all about that… Purescript and its’ many backends. I’ve used purescript in the browser. I’m just learning phoenix (and that uses Elixir). Sticking to the defaults for now. But purescript for a library might be tempting… How is the performance overhead / what does the generated code look like?

That dynamic with the GET request sounds familliar… But it’s fun.

How is the performance overhead

Can’t tell because I haven’t written any “actual” code yet, the book I’m going through focuses on the theory first, but I’m assuming it to be about the same as what I would’ve written anyways because BEAM itself is quite optimized.

what does the generated code look like?

I don’t know Erlang so can’t comment much on this either. I can’t find the source now, but I remember reading somewhere that the author of Purerl decided to not prioritize readability of the output Erlang code. On the other hand, standard library code looks fairly comprehensible to me. Also it’s worth noting that exported functions are all curried, but also overloaded non-curried ones are generated too. Another fun thing is that it looks like that for some of the built-in functions, when calling them from Erlang/Elixir, you’d have to specify their type, e.g.:

iex(1)> :data_tuple@ps.fst {:tuple, 1, 2}
1

But I don’t remember having this when I was testing out creating/manipulating ETS tables from PS, from IEx.

That dynamic with the GET request sounds familliar… But it’s fun.

Yeah and FWIW in PS with Node as the backend it’s much easier because of the Affjax library and a couple examples. In Purerl it’s just Gun which is quite low-level itself and then on top of this there are literally zero docs. But the language itself is very expressive and overall just amazing, I’m enjoying it so far.

2 Likes

With regards to currying, I’ve recently ran some simple tests in Elixir (for clarity – in Elixir alone). The extra overhead was ~25%, regardless of the number of arguments – quite tolerable for me.
Here is some sample code from Data.List:

%-file("/home/me/code/elixir/purescript_test/.spago/lists/v6.0.1/src/Data/List.purs", 829).
-spec transpose(data_list_types_List(data_list_types_List(any()))) -> data_list_types_List(data_list_types_List(any())).
transpose(_@463) -> case _@463 of
  ({ nil }) -> { nil };
  ({ cons, { nil }, _@464 }) -> (transpose(_@464));
  ({ cons, { cons, _@465, _@466 }, _@467 }) -> { cons, { cons, _@465, (mapMaybe(fun head/1, _@467)) }, (transpose({ cons, _@466, (mapMaybe(fun tail/1, _@467)) })) }
end.
%-file("/home/me/code/elixir/purescript_test/.spago/lists/v6.0.1/src/Data/List.purs", 829).
-spec transpose() -> fun((data_list_types_List(data_list_types_List(any()))) -> data_list_types_List(data_list_types_List(any()))).
transpose() -> fun (_@468) ->
  (transpose(_@468))
end.
1 Like
  • dialyzer through elixir-ls. It broke for me years ago on all my machines so i do not anymore. I should try again

  • yes i try to use typespecs anyway for people that do use it. And for myself. But ofc it would be far nicer if i still had typer integration in my editor… But that broke too.

  • no use of incremental. Never needed it plus too new

  • not tried eqwalizer. Would love to try gradient but it says on the tin not ready, so…

1 Like

Unfortunately there is a notable performance overhead with PureScript due to its use of unmonomorphised type classes, and the generated code is quite unfriendly if you’re trying to use it from Erlang or Elixir.
Gleam is designed for this use case so doesn’t have these problems, but does have the same level of type safety.

3 Likes

Ah shoot I should have included Gleam in the poll options. :man_facepalming:

In case anyone uses dialyxir specifically, I asked Jeremy if he’d be willing to set up GitHub sponsors, which he did! So that’s an option now. :smile: Support via GitHub Sponsors? · Issue #488 · jeremyjh/dialyxir · GitHub