Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can a variable be bound twice in a pattern?

Usually, F# does not allow pattern variables to occur twice in the same pattern. But in the following code, F# does not complain - is this a bug?

type foo = { A: int }
let test (x, {A = x}) = x
let result = test ("bla", {A = 3})
like image 751
Mo B. Avatar asked Dec 07 '12 10:12

Mo B.


1 Answers

I don't think this is a bug, although it seems confusing, but it's just the way the compiler compiles the above value binding.

Section 14.6.3 states that if the value definition is not a single value pattern (as is the case here), the elaborated expression is

tmp <typars1… typarsn> = expr
ident1 <typars1> = expr1
…
identn <typarsn> = exprn

where tmp is a fresh identifier and each expri results from the compilation of the pattern pat (§7) against input tmp [from spec].

To see what the compiler does, we could use an F# quotation, e.g.:

<@ let test (x:int, {A = x:int})= x in test (3, {A = 5}) @>;;

In string format I get (leaving some stuff out):

Let (test,
     Lambda (tupledArg,
             Let (x, TupleGet (tupledArg, 0),
                  Let (_arg1, TupleGet (tupledArg, 1),
                       Let (x, PropertyGet (Some (_arg1), A, []), x)))),
     Application (test, NewTuple (Value (3), NewRecord (foo, Value (5)))))

which is why we get the "inner" x.

I don't think it's a bug but perhaps it would be more consistent if this would generate a warning.

like image 96
Marcus Avatar answered Oct 04 '22 20:10

Marcus