4

In a new console application, just pasting the following code leads to the exception "The parameter is not a recognized method name".

  • Does the following code work on your installation?
  • Joker: Do you know any reason why it would not work on mine?

// Learn more about F# at http://fsharp.net
// See the 'F# Tutorial' project for more help.
let somefunction1 arg  = ()
let somefunction2 ()   = ()

open Quotations.DerivedPatterns

let test() =
   let d =  <@ somefunction1() @>
   let e =  <@ somefunction2() @>

   match d with
   | SpecificCall <@ somefunction1() @> (a,b ,c) -> printfn "somefunction"
   | _                                           -> printfn "something else"
   match d with
   | SpecificCall <@ somefunction1   @> (a,b ,c) -> printfn "somefunction"
   | _                                           -> printfn "something else"

   match e with
   | SpecificCall <@ somefunction2() @> (a,b ,c) -> printfn "somefunction"
   | _                                           -> printfn "something else"

   //THIS FAILS HERE saying "The parameter is not a recognized method name"
   match e with
   | SpecificCall <@ somefunction2   @> (a,b ,c) -> printfn "somefunction"
   | _                                           -> printfn "something else"


[<EntryPoint>]
let main argv = 
    test()
    printfn "%A" argv
    0 // return an integer exit code

Looking at the definition of active pattern SpecificCall defined in the compiler I find:

 [<CompiledName("SpecificCallPattern")>]
    let (|SpecificCall|_|) templateParameter = 
        // Note: precomputation
        match templateParameter with
        | (Lambdas(_,Call(_,minfo1,_)) | Call(_,minfo1,_)) ->
            let isg1 = minfo1.IsGenericMethod 
            let gmd = if isg1 then minfo1.GetGenericMethodDefinition() else null

            // end-of-precomputation

            (fun tm -> 
               match tm with
               | Call(obj,minfo2,args) 
#if FX_NO_REFLECTION_METADATA_TOKENS
                  when (minfo1.MethodHandle = minfo2.MethodHandle &&
#else               
                  when (minfo1.MetadataToken = minfo2.MetadataToken &&
#endif                  
                        if isg1 then 
                          minfo2.IsGenericMethod && gmd = minfo2.GetGenericMethodDefinition()
                        else
                          minfo1 = minfo2) -> 
                   Some(obj,(minfo2.GetGenericArguments() |> Array.toList),args)
               | _ -> None)
        | _ -> 
            invalidArg "templateParameter" (SR.GetString(SR.QunrecognizedMethodCall))
Peter O.
  • 32,158
  • 14
  • 82
  • 96
nicolas
  • 9,549
  • 3
  • 39
  • 83
  • When I paste the code from your **Edit #2** in Visual Studio 2012 then it works fine for me. Can you share the compiled assembly somewhere, perhaps there is some difference... Also, what version of F# (etc.) are you using? – Tomas Petricek Oct 22 '12 at 15:53
  • that is very strange. how do we trace all this info ? fusion log ? – nicolas Oct 22 '12 at 16:35
  • Not sure, but if you share the compiled `exe` from your machine, I can try running it to see if there is difference in the compiler we're using or in the `FSharp.Core.dll` that gets loaded. – Tomas Petricek Oct 22 '12 at 17:04
  • Your **Edit #2** example works fine for me in VS2012/.NET 4.5 and VS2010/.NET 4.0. What versions of F#/.NET framework/Visual Studio are you using? – pad Oct 22 '12 at 18:24
  • it works fine at home too. I use VS2012RC/.NET 4.5 at work. Will try to post the binaries tomorrow. Home : FSharp.Core.dll v4.3.50727.0 – nicolas Oct 22 '12 at 18:47
  • I reproduced with another pc at home. I see that FSharp.core.dll is version 4.3.50522.0 both dll have product version '4.3.0.0' – nicolas Oct 22 '12 at 21:05
  • Here is a binary link http://dl.dropbox.com/u/7355414/quotationpb/Debug.zip – nicolas Oct 22 '12 at 21:22
  • and a link to the solution http://dl.dropbox.com/u/7355414/quotationpb/constraints_sln.zip – nicolas Oct 22 '12 at 21:24
  • I cannot reproduce the bug using your solution. I guess it is a bug in VS2012 **RC**, which is fixed in the RTM version. – pad Oct 22 '12 at 23:11
  • I can not reproduce by compiling, but your built binary crashes, so @pad is probably right, this is a compiler bug in VS2012 RC. – Robert Jeppesen Oct 23 '12 at 10:22
  • I can confirm what @RobertJeppesen and @pad say. The compiled assembly is different than the one I get when I compile your code, so we must be using a different compiler. (There is _some_ difference in how the quotations in the `test` function are encoded. This is stored as binary data, so I cannot see _what_ the difference is, but they differ.) – Tomas Petricek Oct 23 '12 at 14:32
  • yes must be a bug. sorry for making you loose time. the doc on quotation seems quite sparse. this 'deep embedding' is used inside stuff like infer.net, solver foundation, statfactory, type providers, but seems quite advanced, in usage at least. – nicolas Oct 28 '12 at 11:50

1 Answers1

2

Offhand, that looks okay to me... Is it possible that you've shadowed the original definition of var somehow? For instance, the following self-contained example works fine for me:

let var<'a>() = Unchecked.defaultof<'a>

match <@ var<int>() @> with
| Quotations.DerivedPatterns.SpecificCall <@ var @> (obj,_,[]) ->
    printfn "var"
| _ -> printfn "something else"
kvb
  • 54,864
  • 2
  • 91
  • 133
  • I should have said in the message, I tried to do something similar to your code, and had the same error. copying/pasting from your example does the same. I will try to have that work in different context (clean project, fsharp version etc..) to find out, this is puzzling. – nicolas Oct 16 '12 at 06:54
  • For me, pasting the code from your edit into a new project works properly. I'm running VS2012. – kvb Oct 16 '12 at 14:36