ijverig
Using guards like this works fine:
iex(1)> defmodule M do
...(1)> def update_position({pos, max_pos}) when pos < max_pos, do: pos + 1
...(1)> end
{:module, M, …
iex(2)> M.update_position({3,4})
4
iex(3)> M.update_position({3,3})
** (FunctionClauseError) no function clause matching in M.update_position/1
The following arguments were given to M.update_position/1:
# 1
{3, 3}
iex:2: M.update_position/1
But when extracting it into a defguard, the compiler gives a syntax error:
iex(1)> defmodule M2 do
...(1)> defguard is_valid_position({pos, max_pos}) when pos < max_pos
...(1)> end
** (ArgumentError) invalid syntax in defguard is_valid_position({pos, max_pos})
(elixir) lib/kernel.ex:4623: anonymous fn/2 in Kernel.validate_variable_only_args!/2
(elixir) lib/enum.ex:737: Enum."-each/2-lists^foreach/1-0-"/2
(elixir) lib/enum.ex:737: Enum.each/2
(elixir) lib/kernel.ex:4592: Kernel.define_guard/3
(elixir) expanding macro: Kernel.defguard/1
iex:2: M2 (module)
Anyone has a clue of the problem here?
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
Hi everyone,
I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding.
I sta...
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
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
So i have been using ash framework for a while and i love it. However currently the issue im having with ash framework is the error handl...
New
Other Trending Topics
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
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
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 everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
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
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











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
NobbZ
You can not pattern match in a defguard.
ijverig
As @NobbZ mentioned, the problem is that there’s no pattern matching inside a
defguardheader.I didn’t find good documentation on this, though. Only some discussion prior to implementing
defguardin v1.6:[1] Provide defguard · Issue #2469 · elixir-lang/elixir · GitHub
[2] Provide defguard · Issue #2469 · elixir-lang/elixir · GitHub
[3] Redirecting to Google Groups
[4] Defguard - experimenting with a structural matching alternative to Kernel.defguard
Follow up question: if I define a guard as a macro (according to the docs) then I can pattern match. However isn’t
defguarda syntactic sugar for this macro?NobbZ
Using a macro you can only pattern match on the AST, not on arbitrary runtime values.
ijverig
But I was able to implement the original idea with a macro:
This is because I’m pattern matching on the AST, not runtime values? Like: I’m pattern matching “structures” (like
{ }) of the language and types, not runtime values?If it works on this macro, shouldn’t it work in the
defguardexpansion? Isn’t it just a macro as well?NobbZ
You are matching on the AST of
{pos, max_pos}, it would not work if you definedM.update_position/1like this:Because
phas a different AST than the tuple which you specified literally before.To be honest, the best way were probably to make this clear as “Klosbrühe” and
defguard is_valid_position(pos, max_pos) when pos < max_posordefmacro is_valid_position(pos, max_pos) do quote(do: unquote(pos) < unquote(max_pos)) end(maybe repair syntax of them).Eiji
@ijverig: You can solve this by:
NobbZ
Yeah that would work, but I prefer the 2 arity version as it makes no assumption about how pos and max_pos are related together.
In any case I’d add
is_integer/1,is_float/1oris_number/1to the guard, it will safe a lot of time spent on debugging when the first time something not numeric slips into the tuple…ijverig
@NobbZ
Yes, I understand.
This was just an example, my need is more something like
is_valid_position({x, y}, {max_x, max_y})so I could callis_valid_position(pos, max_pos). IMHO changing that tois_valid_position(x, y, max_x, max_y)is a bit cumbersome on the readability.But seems to be the way to go
axelson
@ijverig while I haven’t used it you may like the library Expat by @vic
Expat - composable, reusable pattern matching
OvermindDL1
Yeah this is a fantastic set, it essentially absorbed my defguard experiment (that would have worked as OP wanted if it was part of Elixir) but in a way that is stable.