Because ‘#{}’ means “match any map”. Map pattern match usually includes matching list of keys, in this case that list is empty. If you want, use ‘map_size/1’ BIF in a guard to match an empty map.
Elaborating on this, the guard Map =/= #{} compares for non-identity with an empty map, while the match in the function head fun(..., #{}) matches on any map.
This discrepancy between #{} meaning “any map with at least these fields (none, so any map)” and #{} meaning “a map with EXACTLY these fields (none)” came up when I was designing frames. I considered the equivalent of #{ | } – at least these fields – vs #{} – exactly these fields – and indeed being able to say #{ | Rest_Of_Map} looked potentially useful. But #{|} looked ugly. Perhaps #{} – exactly these fields, in all contexts – vs #{…} – at least these fields, only in patterns – would have worked. Too late now.
Sounds good to have both choices, but I actually like that “at least those fields” is the default behavior because you can add fields to maps without breaking working code. #{ | Rest_Of_Map} looks interesting, would it be equivalent to:
Maybe syntax for “exactly those fields” could be a thing, but not with #{} syntax? Because of the current behavior it seems pretty hard with to come up with syntax that is backward compatible and makes sense in matching “exactly those fields”.