vic
Asdf Core Team
Expat is a tiny experiment I did for extracting patterns and being able to reuse them (compose and share patterns between elixir libraries). Look for zombies in the README.
It was born as some of my first attempts at creating composable things like the just released data specification library Spec.
Hope anyone finds it interesting at least.
Trending in Announcing
WebAuthnLiveComponent WebAuthnComponents
See this post about renaming the package.
Passwordless authentication for Phoenix LiveView app...
New
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
I released Doggo, a collection of unstyled Phoenix components.
https://github.com/woylie/doggo
Features
Unstyled Phoenix components....
New
Hi everyone,
I’ve been working on this protobuf library for 3 years. We use it in the company I work for, EasyMile, to communicate with ...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
I’ll shortly be launching Text, a nascent text analysis library.
Current functionality
In this early version (not ready for prime time) ...
New
Following on from my CLDR lbraries I started work on Unicode transforms. But like everything related to CLDR there is a lot of yak-shavin...
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
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with.
But I don’t use it anymore.
Serverless was the promis...
New
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #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
- #ai
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex










First Post!- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
OvermindDL1
Huh, looks to save a lot on readability. Is it mostly just for maps?
Most Liked
josevalim
This is a really nice project. Since you are exploring things on the area, here are some challenges/questions you can consider:
Is it possible to extend expat to be a generalization of records? defpat contains an exact subset of the records functionality, which is the pattern matching one. It is also easy to see how
defpatcould be used for updates, all you need to do is to match on the value and then build another new value of exactly the same shape with the same variables in place except the ones you are replacing, etc.Have you considered using another operator instead of
=for mixing patterns? I believe your mixing of patterns is actually an intersection. If you assume that%{"id" => id}will match all maps with the"id"field, including%{"id" => "foo", "name" => "baz"}, and the pattern%{"name" => name}all maps with a"name"field, including the map mentioned above, when you specifyid() = name()you are actually saying it should have BOTH patterns,id()ANDname(). If you think of patterns as sets representing the structures they can match on, it is an intersection. Another reason to choose another operator is that the precedence will work in a way it won’t require parentheses, for example:defpat subject id() &&& name(). Here is a list of operators.There is one feature we could add to Elixir that would allow the library to become more powerful which is to allow guards inside patterns:
Of course nobody would write such in practice but supporting it would allow you to express patterns with guards:
Which the Elixir compiler would then rewrite internally as:
Anyway, this is very exciting and it is close to topics I am currently researching.
I could expand more on both points above if you are interested. For example, if you are able to generalize defpat to records, you should also be able to generalize it for map updates, and if you define a pattern such as:
And then allow someone to update the nested tuple like this:
Optimizations could allow you to compile
foo_bar_bazto%{map | "foo" => Map.fetch!(map, "foo") |> put_elem(0, 3)}.vic
Hey, good news, I’ve just released v1.0, I did a major rewrite as I really wanted (and needed) it to support guards. Wrote much a much better README guide (I guess) and also documented it more.
The only thing I removed from v0 is the
...syntax as it introduced all variables in scope and it was mostly a pain since elixir 1.5. So now you have to be explicit on what you bind.Hope the guide explains a bit better where this library fits and how it could be used.
<3
Edit. Forgot to mention, for @josevalim, in the example using guards from the readme,
expat defjust expands the inner patterns and collects (anding) any guards produced by them, and finally just ands those with any from the function definition. here’s the codeibgib
Yeah, this is definitely my favorite new library. The primary gain from it for me is making things DRYer. Where before I would have map structures repeated in multiple function clauses, e.g.
which has redundancy in the
"var_name" => var_name, as well in the function clause level. Anddest_ibandsrc_ib_gibare used across multiple commands in many places. I’m now able to create a single file for the reused patterns:(NB: I am tacitly going with a
_suffix to indicate a pattern vs the var name, but I’m not sure what other non-word characters are legal in elixir. I would rather prefix the pattern with a single character and would love any suggestions.)And then I compose them above the function and consume them:
EDIT: The
...inside the pattern is literal syntax, which helps enormously with DRY. The other..just means other args.This is ridiculously more DRY and readable. Definitely a powerful lib you made here!
Thank you!
Last Post!
marciol
I’m thinking that expat can be a simple way to improve readability and also it allows a way to do a sort of contract check at function boundaries. Is this the way to follow or the Elixir community are agreeing on other approaches?