Proposal: Warn on assert %{} = x

71 views
Skip to first unread message

Wojtek Mach

unread,
Aug 16, 2022, 5:55:09 AM8/16/22
to elixir-lang-core
Hi,

Developers can easily shoot themselves in the foot if they write:

    assert %{} = x

but really what they meant was to write:

    assert %{} == x

The mistake is writing `=` instead of `==`, an easy one to make. The difference is of course that the former will succeed on _any_ map and the latter will _only_ succeed on an _empty_ map.

I'd like to propose ExUnit warn on `assert %{} = x` and tell users to instead write `assert is_map(x)`.

Thoughts?

P.S. In my projects I'd either write `assert actual == expected` OR `assert expected = actual` and never `assert expected == actual` exactly because it is easy to make the mistake. Maybe there is a Credo check to enforce such style.

Ben Wilson

unread,
Aug 16, 2022, 5:59:39 AM8/16/22
to elixir-lang-core
To me this feels like a good use of credo or similar linter, not something that the Elixir compiler itself should warn about. `assert %{} = x` isn't the most idiomatic way to match but it isn't incoherent or invalid, just probably not best practice.

Wojtek Mach

unread,
Aug 16, 2022, 6:17:03 AM8/16/22
to elixir-l...@googlegroups.com
Just to be clear what I proposed was not a change in the compiler, just changing ExUnit's assert macro to emit the warning under that specific scenario.

-- 
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/b70a4bb4-14d4-4ea3-8b49-45b408abf750n%40googlegroups.com.

Sabiwara Yukichi

unread,
Aug 16, 2022, 7:19:28 AM8/16/22
to elixir-l...@googlegroups.com

I don't think this would solve the issue completely though: should we then warn for nested maps like `[%{}] =` or `{:ok, %{}} =`? (which might be intended)
Also, people might be writing `%{name: "foo"} =` actually meaning `%{name: "foo"} ==`, but I don't think we should warn on these.

> my recommendation is to always do `assert actual == expected` and `assert expected = actual`, never `assert expected == actual`

I really like this suggestion you made in the previous thread, it helps a lot distinguishing between matches and equality, maybe it could be encouraged in the official docs?



Wojtek Mach

unread,
Aug 16, 2022, 7:28:46 AM8/16/22
to elixir-l...@googlegroups.com
Oh wow, I totally forgot about that thread from last year. There was some more discussion [1], a PR with reference implementation of this change [2] and even a PR in the wild that this change would have caught [3]. Thank you for linking to it!

luk...@niemier.pl

unread,
Nov 10, 2023, 10:38:37 AM11/10/23
to elixir-lang-core
Yeah, I have proposed that and I still strongly believe that it is what should be done in the repo, as it is something that you can easily trip over.
Reply all
Reply to author
Forward
0 new messages