lud

lud

Please explain inconsistency with :erlang.map_get(key, map) in guards

Hi,

If in a guard I use :erlang.map_get/2 on a map that does not have the key, and use a or to put another guard condition in second position, the second condition will not be evaluated.

defmodule T do
  def check_nil_1(map, key) when :erlang.map_get(key, map) == nil or not is_map_key(map, key),
    do: true

  def check_nil_1(_, _),
    do: false

  def check_nil_2(map, key) when not is_map_key(map, key) or :erlang.map_get(key, map) == nil,
    do: true

  def check_nil_2(_, _),
    do: false
end

map = %{a: 1}
key = :b

T.check_nil_1(map, key)
|> IO.inspect(label: "check 1")

T.check_nil_2(map, key)
|> IO.inspect(label: "check 2")

# Output:
# check 1: false
# check 2: true

I expected both checks to be true. The only difference is the order of the conditions in the guards. The documentation says:

The call fails with a {badmap,Map} exception if Map is not a map, or with a {badkey,Key} exception if no value is associated with Key. […] Allowed in guard tests.

Obviously as it is in a guard it does not fails with an error, but the docs do not tell that it also skips further evaluation of the guard conditions.

So, are there any more docs on that subject ? And any other special cases in guards that would be good to know ?

Thank you

(edit: if the key exists in the map with a nil value, both checks return true as expected.)

Marked As Solved

josevalim

josevalim

Creator of Elixir

map_get raises if the key does not exist on the map and or only executes the right-side if the left-side is false. Therefore, in the first case, when you do the map_get for a key that does not exist on the map, it will fail and never execute the right-hand side of or.

Also Liked

Qqwy

Qqwy

TypeCheck Core Team

As an alternative if you want a particular function clause to be called even if an earlier guard of this clause raises, you might use multiple guards in the same clause.

Where Next?

Popular in Questions Top

gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
sabri
Can someone explain the settings of pool_size of Ecto in config file? and what is the recommend size? Thanks
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
jc00ke
Expanding on this topic: https://forum.elixirforum.net/t/map-typespec-question/19217 Let’s say I have a map with required and optional k...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement