Skip to content

Provide bare and opt set operations#15433

Merged
josevalim merged 9 commits into
mainfrom
jv-opt-descr
Jun 10, 2026
Merged

Provide bare and opt set operations#15433
josevalim merged 9 commits into
mainfrom
jv-opt-descr

Conversation

@josevalim

Copy link
Copy Markdown
Member

This pull request breaks set operations (union, intersections, differences, and negations) into bare and opt (optimized). This is a large PR but most changes are mechanical:

  • All functions outside of the Descr module use the optimized versions
  • The Descr module uses the bare versions for everything, except for to_quoted and type "mutators" (tuple_update, map_delete, etc)

Therefore, to review this code, it is best to open up the descr.ex module and see if the usage of opt_* functions within that module are acceptable. There are not many of them.

Comment thread lib/elixir/test/elixir/module/types/expr_test.exs Outdated
@josevalim josevalim merged commit 9f24a45 into main Jun 10, 2026
23 of 25 checks passed
@josevalim josevalim deleted the jv-opt-descr branch June 10, 2026 17:37
@josevalim

Copy link
Copy Markdown
Member Author

💚 💙 💜 💛 ❤️

@sabiwara

Copy link
Copy Markdown
Contributor

@josevalim sorry I just noticed this change now, just a couple of questions.

I was wondering, if the bare_ variation is only meant for internal use in Descr, perhaps we don't need to rename the opt_ one? Having opt_union etc in tests or when playing in the shell feels a bit like clutter.

Also, I didn't fully understand the logic behind bare_, is the following guess correct?

  • when building up types, e.g. during inference, to prevent explosion, we want to optimize as we go -> opt_
  • when just type checking against an expected, we don't want to compute new types on the fly -> bare_
    Perhaps a comment in the code above bare/opt distinction could be helpful for the future.

@josevalim

Copy link
Copy Markdown
Member Author

Yes, you are correct.

I decided to go with two separate functions to force whoever is writing code to think exactly which one to use, instead of doing it automatically. :)

@josevalim

Copy link
Copy Markdown
Member Author

Basically, the goal is: whenever we are checking for subtyping, emptiness, etc, we need to perform unions, intersections, differences, and so on. In those cases, we don't want to optimize, so we do bare. Also, once we introduce recursive types, we can't optimize inside constructors, so those are bare too. Everything else can likely be optimized.

@sabiwara

Copy link
Copy Markdown
Contributor

Thanks for clarifying! 🙇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants