[erlang-questions] erl_syntax_lib:annotate_bindings/1 and bounded variables in patterns

Salvador Tamarit stamarit@REDACTED
Tue Jun 20 11:50:18 CEST 2017


Hi,

we have been using erl_syntax_lib:annotate_bindings/1 for a transformation
that needs to know the variables binding to proceed. One of the critical
points is to know whether a variable in a pattern is bound or not. We have
found an unexpected behaviour in the way the bindings are annotated. Let's
see an example:

Suppose we have the following piece of code:

A = 3,
B = 2,
case ... of
       {*{D,D}*,{A,D},D} ->
           ...
end

Calling to erl_syntax_lib:annotate_bindings/1 with the pattern of the
clause as argument produce the following erl_syntax's AST (we show only a
snippet of it):

{tree,tuple,

{attr,6,[{env,['A','B']},{bound,['C','D','E','F']},{free,['A']}],none},
      [{tree,tuple,
             {attr,6,[{env,['A','B']},{bound,['D']},{free,[]}],none},
             [{wrapper,variable,
                       {attr,6,[{env,['A','B']},*{bound,['D']}*
,{free,[]}],none},
                       {var,6,'D'}},
              {wrapper,variable,
                       {attr,6,[{env,['A','B']},*{bound,['D']}*
,{free,[]}],none},
                       {var,6,'D'}}]},
       ....]}

We would expect that the second occurrence of variable D were considered as
bound  since it has been bound in its first occurrence. Further occurrences
of D in the pattern are also considered as unbound. This is something that
is true when you consider the pattern as a whole, but not if you consider
how it is supposed to be evaluated. We have been discussing about two
alternatives for the evaluation of these patterns: In both the first thing
is to substitute the variables in the environment before evaluating the
pattern. Then, one option is that each time a variable is found it is bound
and then compared to the current pattern environment, i.e. first D puts the
value of D in the environment, then the second occurrence of D is assigned
to whatever and then matched with the environment. The second approach is
that once a variable is bound in the pattern, a substitution is applied to
the the rest of the pattern, i.e. if {3, 3, 4, 5} is matched with {D, D, E,
F}, after evaluating the first D the pattern becomes {3, 3, E, F}.  In any
case, we wonder if independently of how the pattern is evaluated, maybe the
binding annotated by erl_syntax_lib:annotate_bindings/1 would be more
useful if they considered as bound  the second occurrence of D in the
example above. In a similar way that when we have an expression (not
pattern) tuple {X = 3,X}, where the second X is annotated as bound.

Thanks in advance.
Salvador Tamarit
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170620/77d715ed/attachment.htm>


More information about the erlang-questions mailing list