dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.94k stars 788 forks source link

Different interpretaiton of specific quotation in VS2017 vs VS2015 #3698

Closed alex-bogomaz closed 7 years ago

alex-bogomaz commented 7 years ago

Following quotation expression is parsed/interpreted/decompiled differently across F# 4.0 and F# 4.1:

let ftupled (a,b) c d = a + b + c + d + 1

<@ ftupled (1,2) @>

Repro steps

  1. In VS 2015 FSI outcome is the following:
    
    Microsoft (R) F# Interactive version 14.0.23413.0

let ftupled (a,b) c d = a + b + c + d + 1;;

val ftupled : a:int * b:int -> c:int -> d:int -> int

<@ ftupled (1,2) @>;; val it : Quotations.Expr<(int -> int -> int)> = Let (tupledArg, NewTuple (Value (1), Value (2)), Let (a, TupleGet (tupledArg, 0), Let (b, TupleGet (tupledArg, 1), Lambda (c, Lambda (d, Call (None, ftupled, [a, b, c, d])))))) {CustomAttributes = [NewTuple (Value ("DebugRange"), NewTuple (Value ("stdin"), Value (2), Value (3), Value (2), Value (16)))]; Raw = ...; Type = Microsoft.FSharp.Core.FSharpFunc2[System.Int32,Microsoft.FSharp.Core.FSharpFunc2[System.Int32,System.Int32]];}

2. In VS 2017:

Microsoft (R) F# Interactive version 4.1

let ftupled (a,b) c d = a + b + c + d + 1;; val ftupled : a:int * b:int -> c:int -> d:int -> int

<@ ftupled (1,2) @>;; val it : Quotations.Expr<(int -> int -> int)> = Let (a, Value (1), Let (b, Value (2), Lambda (c, Lambda (d, Call (None, ftupled, [a, b, c, d]))))) {CustomAttributes = [NewTuple (Value ("DebugRange"), NewTuple (Value ("stdin"), Value (2), Value (3), Value (2), Value (16)))]; Raw = ...; Type = Microsoft.FSharp.Core.FSharpFunc2[System.Int32,Microsoft.FSharp.Core.FSharpFunc2[System.Int32,System.Int32]];}


#### Expected behavior
Should be the same, and it seems that in VS2017 quotation is interpreted incorrectly - tuple ```(a, b)``` is missing - could you please clarify this?

Found this when compiling https://github.com/SwensenSoftware/unquote/ using VS 2017

dsyme commented 7 years ago

I think we regard this as a bug fix, and expect historical consumers of quotations to be able to process either form

alex-bogomaz commented 7 years ago

thanks for clarification

alex-bogomaz commented 7 years ago

closing

stephen-swensen commented 5 years ago

Sorry for commenting on this long closed issue, but FYI - it appears that there is information loss in the new quotation representation such that it is not possible to decompile <@ ftupled (1,2) @> as "ftupled (1,2)". That is, when we have a function partially applied with a tuple in the first arg, it has the same exact representation as a function partially applied with all non-tuple args:

let ftupled (a,b) c d = a + b + c + d + 1
<@ ftupled (1,2) @>

> <@ ftupled (1,2) @>;;
val it : Quotations.Expr<(int -> int -> int)> =
  Let (a, Value (1),
     Let (b, Value (2),
          Lambda (c, Lambda (d, Call (None, ftupled, [a, b, c, d])))))
    {CustomAttributes = [NewTuple (Value ("DebugRange"),
          NewTuple (Value ("stdin"), Value (6), Value (3), Value (6), Value (16)))];
     Raw = ...;
     Type = Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32]];}

and

let ftupled a b c d = a + b + c + d + 1
<@ ftupled 1 2 @>

> <@ ftupled 1 2 @>;;
val it : Quotations.Expr<(int -> int -> int)> =
  Let (a, Value (1),
     Let (b, Value (2),
          Lambda (c, Lambda (d, Call (None, ftupled, [a, b, c, d])))))
    {CustomAttributes = [NewTuple (Value ("DebugRange"),
          NewTuple (Value ("stdin"), Value (8), Value (3), Value (8), Value (14)))];
     Raw = ...;
     Type = Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32]];}