matthias_toepp
I’m new to Elixir…having looked into languages like Haskell, Elm, and Gleam, I’m wondering if Elixir’s new type system will permit sum types to be declared and used with exhaustiveness checking? (Presumably, new syntax would be required for this.)
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’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
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
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
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
I’m trying to set up Emacs with elixir-ls via lsp-mode and credo via Flycheck. This should mostly be preconfigured as Flycheck picks up c...
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
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
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
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
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #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)
dimitarvp
Oh, I would very much like to know as well.
al2o3cr
Why? I’d expect they’d be written in the BEAM “tuple with a leading atom” idiom. A complex example, from
gen_statem:Exhaustiveness checking is mostly a difference of interpretation; if Dialyzer sees code like this:
it will assume that
some_function_that_returns_actioncan’t return the other variants ofactionand try to derive a contradiction. It will also complain about dead code if subsequent analysis provessome_function_that_returns_actionnever returns:pop_callback_module.billylanchantin
I don’t believe so. A sum type is a concept from algebraic type systems. Elixir’s type system will use set theoretic types. Briefly,
Algebraic types have:
Set theoretic types have:
In both systems, you build more complicated types from the respective primitives. But although there are similarities, the way you compose the types are different.
However,
From the technical paper:
So although there are no sum types, I believe there will be exhaustiveness checking.
Disclaimer: I have no inside knowledge! I’m just following along as best I can.
matthias_toepp
@dimitarvp @billylanchantin
Thanks for helping me to get a better understanding of this.
stevensonmt
Theoretical underpinnings aside, is there any practical difference between an algebraic sum type and a set theoretic union type? Taking the example
and translating to something using ADTs like Rust (please excuse likely errors in this example as I haven’t written Rust in a long time and I’m a bit, errr, rusty):
billylanchantin
This is a great question and I’m not qualified to answer it fully. I think once us Elixir developers get their hands on the upcoming typing tools, the community will be clamoring articles with titles like these:
But I’ll take a stab. Here is one example of how sum types differ from union types: as I understand it, sum types are “tagged” while unions are “untagged”. Take this example:
Here,
:blueis automatically a member ofscifi_colors(). There’s no notion of “which”:blueyou mean since the union is untagged (it doesn’t matter where it came from).Contrast that with
enumfrom Rust. If you start with twoenums:There’s no way to combine them such that you get a flat collection of the inner types. You’re stuck with doing things like:
With
ScifiColors1,Blueis not a member since you need to specifyMatrixPills(Blue)orLightSabers(Blue)(i.e. you have to “tag”Blue). WithScifiColors2,Blueis a member but the definition makes no reference to the originalenums. So you didn’t really combine them like we were able to with union types.(This doesn’t mean tagged unions are bad! They’re just different.)
I highly recommend José’s talk from ElixirConf if you want to learn more:
antoine-duchenet
From my point of view, since the 3 members of your union are disjoint / clearly discriminated, I don’t see any practical difference with a sum type (in fact they look to me like tagged union members).
It would however be trickier with shape-compatible structs, should the struct name behave as a discriminant if the inner data has the same shape ?
stevensonmt
What a great explanation of the differences. Thanks for taking the time!
@antoine-duchenet – since Elixir structs are maps with a private
__struct__field I would assume the struct name could be matched on or not just as any other field.could be satisfied by any struct that matches on the specified fields.
So I would expect that the
__struct__field would get ignored unless the definition of the type specifically matches on that field.antoine-duchenet
Yes indeed !
My question was more about the behavior desired by the community than the expected behavior with the “current” implementation, expecially concerning exhaustiveness checking.
With something like that :
Which could be considered as syntaxic sugar to write this :
If the
outputtype behaves like an union type (the way you assume it would), simplified to something liketype result() = %{__struct__: :Dog or :Cat, name: string()}, I’d expect thehandle/1function not to raise a “not exhautive” warning because its matching (seen as a set) “contains” every possible value of theresulttype.To raise a warning, we would have to define
def handle(%Dog{name: name}), do: "Hello #{name}"because this definition does not handle the%Cat{}case.In an hypotetical world where the
__struct__field receives some special treatment to behave like the discriminant of the sum (a.k.a. the tag of the tagged union), we could imagine thehandle/1function to raise a “not exhautive” warning because its matching (seen as a set) is fully disjoint with theresulttype (it could be seen as if it meantdef handle(%{__struct__: nil, name: name})). This behavior would be closer to the enum wrappers often used in Rust likeOk/Err.In such a world, we would have to define
def handle(%Dog{name: name})anddef handle(%Cat{name: name}).I’m personally fine with 1. since it looks more Elixirish and flexible to me but 2. may have some benefits.
stevensonmt
The way you have defined the result type does match on
__struct__though, so I would expect in that situation for option #2 to be enforced because while allCatsand allDogscontainnamesnot every map that contains anamewill be aDogor aCatand therefore not sufficient to satisfy the typeresult.