SwensenSoftware/unquote

Support WithValue expressions (i.e. ReflectedDefinition(true))

0x53A opened this issue · 3 comments

0x53A commented

I want to run "isomorphic" unit tests between .NET and Fable.

Fable doesn't support Quotations, so I had the idea to use ReflectedDefinitionAttribute - that way I can write my code without the <@ @> and it should work either as a expression or just as a normal parameter.

type T =
#if !FABLE_COMPILER
    static member test ([<ReflectedDefinition(true)>] x:Microsoft.FSharp.Quotations.Expr<bool>) = Swensen.Unquote.Assertions.test x
#else
    static member test x = Fable.Core.Testing.Assert.AreEqual(true, x)
#endif

[<EntryPoint>]
let main argv =

    let fn1 = (fun _ ->
        let state = 1        
        T.test ((state = 1))
    )

    let fn2 = (fun _ ->
        let state = 1
        Swensen.Unquote.Assertions.test <@ state = 1 @>
    )

    
    fn2() // works
    fn1() // fails
    0

But this seems to prouce a slightly different expression tree and then fails:

this expression should not be possible: WithValue (true, Value (true))

Unhandled Exception: Swensen.Unquote.AssertionFailedException: Test failed:

WithValue (true, Call (None, op_Equality, [ValueWithName (1, state), Value (1)]))
WithValue (true, Value (true))
System.Exception: this expression should not be possible: WithValue (true, Value (true))
   at Swensen.Unquote.Evaluation.eval(FSharpList`1 env, FSharpExpr expr)
   at Swensen.Unquote.Reduction.reduce(FSharpList`1 env, FSharpExpr expr)
   at Swensen.Unquote.Reduction.loop@126(FSharpList`1 env, FSharpExpr expr, FSharpList`1 acc)

   at Program.T.test(FSharpExpr`1 x) in C:\Users\rieluk\Source\Repos\unquoteRepro\unquoteRepro\Program.fs:line 6
   at Program.fn1@12T.Invoke(a _arg1) in C:\Users\rieluk\Source\Repos\unquoteRepro\unquoteRepro\Program.fs:line 14
   at Program.main(String[] argv) in C:\Users\rieluk\Source\Repos\unquoteRepro\unquoteRepro\Program.fs:line 24

Thanks for reporting. At first glance it looks more like an issue with decompiling the ValueWithName quoted expression than with working with ReflectedDefinition quotations in general.

Also: cool idea for running "isomorphic" tests!

@0x53A hi - looking at this more closely in earnest now as part of #146 ...

This is failing because of the new expression type WithValue introduced by https://github.com/fsharp/fslang-design/blob/master/FSharp-4.0/AutoQuotationDesignAndSpec.md ... I'll work on supporting this, but in the mean time, I think you can just change your use of the ReflectedDefinition attribute from ReflectedDefinition(true) to ReflectedDefinition(false).