mrkurt
I’m reading through the type annotations features and trying to figure out how to enforce type checking in a Phoenix app. I’m pretty sure it has something to do with the dialyzer. ![]()
Given a project with functions like this, how can I type check it before releasing? The VS Code extension gives me convenient yellow squigglies when my annotations don’t map the derived types. It’s a start, but I want it to be more strict.
@type presence_entry :: {any(), %{metas: list(%{ atom() => any() })}}
@spec presence_by_region(list(presence_entry)) :: %{any() => non_neg_integer()}
def presence_by_region(presence) do
result = presence
|> Enum.map(&(elem(&1,1)))
|> Enum.flat_map(&Map.get(&1, :metas))
|> Enum.filter(&Map.has_key?(&1, :region))
|> Enum.group_by(&Map.get(&1, :region))
|> Enum.sort_by(&(elem(&1, 0)))
|> Map.new(fn {k,v}-> {k, length(v) } end)
result
end
Trending in Questions
Hey guys,
I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly
Do you guys have any suggestions what is the best prac...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
Anyone here using Honeybadger?
My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of
Bandit.HTTPError...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
There are three potential reasons for members of this forum to have a look at https://vutuv.de
You are tired or annoyed of LinkedIn.
Yo...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Adzz
The thing to keep in mind is that fundamentally you can’t. Elixir is not typed, if you come from another typed language you should let go of that expectation or you will be disappointed.
HOWEVER, there are tools to help solve similar problems. Dialyzer is one, but it is not a static type checker, it does success typing. It’s important to know the difference, its limitations and what it aims to do.
Similarly, there are libraries like Norm and Hammox that can give you extra safety if you need it but again they approach the problem differently.
Finally if you want a statically typed language on the BEAM check out Gleam or Caramel.
Nicd
This is actually Dialyzer. So what you get with the VSCode extension is pretty much as far as Dialyzer can go.
mrkurt
I’m fine with a build step.
I mean, I’d love a full static type system but annotations + static analysis seem like they could be enough.
axelson
The general starting point would be to add dialyxir to your project:
https://github.com/jeremyjh/dialyxir/
That will give you a
mix dialyzertask that you can use for CI to fail the build. Although if you don’t start this at the beginning of a project it can be quite difficult to add later because it can be very difficult to understand all the dialyzer errors, dialyzer is rather hamstrung since it has to rely on success typing.dimitarvp
If you are okay with runtime checks with meaningful error messages then using
Domo,TypedStruct(which Domo uses) andEnumTypehave worked really well for me.As for real compile-time static typing, so far there’s no such thing in the BEAM ecosystem although Facebook has announced that they are working on it.
baldwindavid
Adding to the runtime options, I have been happy using TypeCheck (Guide/Readme — TypeCheck v0.13.7). The specs are written nearly the same as regular typespecs, so it feels familiar.
Beyond that, heavy use of function head pattern-matching and guards can get you a long way in enforcing correctness.
Adzz
Except Gleam and Caramel, right?
ityonemo
I’ve taken a bit of a break from it (life is busy since I’m moving cities and I am architecting code at work) but I’m working on a compile-time static type checker for elixir. It should be more powerful/useful than dialyzer since it takes some stances on what types mean and it will have type literals and subtraction types.
It’s nowhere near there yet though, ha.
dimitarvp
So I hear, never tried them still though.
mattludwigs
I think maybe the spec could be:
Dialyzer always assumes the most generic types possible, so since the code provided does not explicitly call anything on the
any()it just assumes this can be anything, as the function will work if you pass anything into it for that parameter. I have found over the years that the more explicit you can be in telling Diazlyer your intentions the better it will type check across the codebase. That is why I recommend making a new type for theany()s -region()andid().While Dialyzer isn’t very strict by default you can try to add a few flags to your Dialyzer configuration and just be explicit as possible. Plus I have found that being super explicit in types helps provide documentation on how the code is intended to work.
Another thing I might consider with this code is turning the presence entry into a struct and providing some function to make a Phoenix presence into this more known data structure (please note I am making a few assumptions here around naming, field, and types).
The exact names and types might be different depending on your codebase. I might even move the
from_presence_entry/1up a level in the API.The reason I would do something like this is that not only is the code explicit to the reader, which is nice, it tells Dialyzer a lot of information, which as the codebase grows will help make Dialyzer seem more strict. However, I know that the community has various degrees of opinions on structs and Dialyzer. While this way of writing typed Elixir requires more typing I found it very useful over the years.
Here’s an example of the Dialyzer flags we set on most of our projects: vintage_net_mobile/mix.exs at main · nerves-networking/vintage_net_mobile · GitHub