What:
I suggest allowing lists:member/2 (or a new erlang:is_list_member/2) to be allowed in guard clauses when the list is a literal term similar to how you can use erlang:is_integer:3 but for a set of distinct known-at-compile-time values.
Why:
It makes it easier to read/write clauses which applies when a variable matches a distinct set of values.
% today, many overloads:
old_foo({const0, Value}) ->
% func_body...
Ret;
old_foo({const1, Value}) -> ...;
old_foo({const2, Value}) -> ...;
% ...
foo({constN, Value}) -> ...;
% today, chain of 'orelse':
old_foo({Key, Value}) when Key =:= const0 orelse Key =:= const1 orelse ... ->
% func_body...
Ret.
% proposed:
new_foo({Key, Value}) when lists:member(Key, [const0, const1, const2, ... constN]) ->
% func_body...
Ret.
This is arguably already possible today by using parse_transform, but it does feel a bit hacky to do it that way.
==IN EXPR==
in_foo(I) when lists:member(I, [1, 2, 3]) -> I + 1.
==IN FORMS==
{function,0,in_foo,1,
[{clause,
{6,1},
[{var,{6,5},'I'}],
[[{call,
{6,13},
{remote,{6,18},{atom,{6,13},lists},{atom,{6,19},member}},
[{var,{6,26},'I'},
{cons,
{6,29},
{integer,{6,30},1},
{cons,
{6,32},
{integer,{6,32},2},
{cons,{6,34},{integer,{6,34},3},{nil,0}}}}]}]],
[{op,{7,7},'+',{var,{7,5},'I'},{integer,{7,9},1}}]}]}
==OUT EXPR==
out_foo(I) when I =:= 1 orelse I =:= 2 orelse I =:= 3 ->
I + 1.
==OUT FORMS==
{function,0,out_foo,1,
[{clause,0,
[{var,{6,5},'I'}],
[[{op,0,'orelse',
{op,0,'=:=',{var,{6,26},'I'},{integer,{6,30},1}},
{op,0,'orelse',
{op,0,'=:=',{var,{6,26},'I'},{integer,{6,32},2}},
{op,0,'=:=',
{var,{6,26},'I'},
{integer,{6,34},3}}}}]],
[{op,{7,7},'+',{var,{7,5},'I'},{integer,{7,9},1}}]}]}