Qqwy

Qqwy

TypeCheck Core Team

Macro idea: total case statements

Hi everyone!

I recently had an idea. This is by no means a revolutionary concep, and other people probably have thought about it before (but maybe not in the context of Elixir), but I think it might be a useful one.

I have not gotten around to (attempt to) implement it yet. I do think it is possible (and of ‘average’ implementation difficulty. Not trivial, but not ridiculously hard either), but I would like to give the community the opportunity to shoot holes in the idea, as well as gauge if I am the only one excited about this, or if other people would like to use it as well.

Total Case Statements

It is very frequent that we pattern-match in a case-statement or function-head on the different possibilities a value might take. Of course, since Elixir is a dynamically/unityped language, a value might be ‘anything’ at any given time, but usually we expect only one of a small subset of these values, especially when we are using a(n approximation of a) sum type. Examples of those are for instance:

  • true | false,
  • [] | [head | tail]
  • :lt | :gt | :eq
  • {:ok, value} | {:error, problem}-tuples,
  • Ecto.action() :: nil | :insert | :update | :delete | :replace | :ignore
  • The atom-names of the fields in your struct.
    etc.

Now, it would be nice if we can somehow indicate that there is a case-statement where we expect such a sum type, and we want to make sure that we have cases for all possible values of that type. In a statically-typed language, this is usually built-in. In a dynamic language, it is not. But if we indicate to the case-statement the typespec that we want to handle, then it could be able to check if we have implemented clauses for each of the inhabitants of the type.

So I propose a macro, with a signature like e.g. total_case typespec, value do ... end, which could be implemented in a library, which would:

  1. Check, at compile-time, if the different match-handlers in the block together cover all possibilities of the type that is passed in.
  2. Maybe (if possible and not ridiculously hard to implement) warn about clauses that prevent later clauses from ever matching.
  3. After this check, compile down to a simple case value do ... end.

Sounds this useful to anyone?
The main thing that I don’t know about currently (besides having not enough spare time to start working on this right away) is how easy it is to programmatically interpret typespecs at compile-time.
It might also be possible that Dialyzer/Dialyxir already does some case-checking; this is something I don’t know, since until today I have struggled to set up + configure Dialyzer properly for my code. But even then I think that having a macro that would enforce this behaviour once set up would make a lot of sense over/alongside using an opt-in typechecker.

What do you think?

Most Liked

lpil

lpil

Creator of Gleam

I think this would be fantastically useful and I previously started work on such a macro before getting distracted by Gleam.

You can see the API I was working with here → sum/lib/sum.ex at master · lpil/sum · GitHub

If you build it I certainly would use this :slight_smile:

OvermindDL1

OvermindDL1

Yep, but it’s also not ‘total’, meaning that if something new is added elsewhere it may (often won’t) catch it and tell you to add a case for it.

LostKobrakai

LostKobrakai

Isn‘t a function with many heads essentially a case statement, which you can typespec?

Where Next?

Popular in Discussions Top

Jayshua
I recently came across the javascript library htmx. It reminded me a lot of liveview so I thought the community here might be interested....
New
andre1sk
A big advantage to Elixir is all the distributed goodness but for many applications running on multiple nodes having integrated Etcd, Zoo...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
MarioFlach
Hello, I want to share a project I’ve been working on for a while: https://github.com/almightycouch/gitgud Background Some time ago I ...
New
axelson
Decided against including more info in the title, but the gist is that Plataformatec sponsored projects will continue with the assets bei...
New
WolfDan
After doing a port from a c++ library to my project in phoenix I’ve seen that I need a faster way to run this algorithm and I found this ...
New
mmmrrr
Just saw that dhh announced https://hotwire.dev/ Is it just me or is this essentially live view? :smiley: Although I like the “iFrame-e...
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
lucaong
Hello Elixir and Nerves community, I have been working for a while on an open-source embedded key-value database for Elixir, that I call...
230 13924 124
New
IVR
Hi all, I’ve seen a number of related threads in the past, but I’d still be very curious to hear an up-to-date opinion on this topic. I...
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
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 Postgres...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
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
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
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
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement