Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6070563
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T09:56:52+00:00 2026-05-23T09:56:52+00:00

I’m at the moment doing some very basic pattern matching with quotations. My code:

  • 0

I’m at the moment doing some very basic pattern matching with quotations.

My code:

let rec test e =
    match e with
    | Patterns.Lambda(v,e) -> test e
    | Patterns.Call(_, mi, [P.Value(value, _); P.Value(value2, _)]) -> 
        printfn "Value1: %A | Value2 : %A" value value2
    | Patterns.Call(_, mi, [P.Value(value, _); P.PropertyGet(_, pi, exprs)]) ->
        printfn "Value1: %A | Value2 : %A" value (pi.GetValue(pi, null))
    | _ -> failwith "Expression not supported"


let quot1 = <@ "Name" = "MyName" @>
(* Call (None, Boolean op_Equality[String](System.String, System.String),
      [Value ("Name"), Value ("lol")]) *)

let quot2 = <@ "Name" = getNameById 5 @>
(* Call (None, Boolean op_Equality[String](System.String, System.String),
      [Value ("Name"),
       Call (None, System.String getNameById[Int32](Int32), [Value (5)])]) *)

test quot1 // Works!
test quot2 // Fails.. Dosent match any of the patterns.

Is it possible to somehow evaluate the result of the getNameById function first, so that it will match one of the patterns, or am I doomed to assign a let binding with the result of the function outside the quotation?

I’ve tried playing with the ExprShape patterns, but without luck..

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T09:56:52+00:00Added an answer on May 23, 2026 at 9:56 am

    You can use PowerPack’s Eval to evaluate only the arguments to the Call expression:

    match e with
    | Call(_,mi,[arg1;arg2]) ->
      let arg1Value, arg2Value = arg1.Eval(), arg2.Eval()
      ...
    

    And similarly for Lambda expressions, etc. Noticed this frees you from enumerating permutations of Value, Property, and other argument expressions.

    Update

    Since you want to avoid using Eval (for good reason if you are implementing a performance conscious application), you’ll need to implement your own eval function using reflection (which is still not lightening fast, but should be faster than PowerPack’s Eval which involves an intermediate translation of F# Quotations to Linq Expressions). You can get started by supporting a basic set of expressions, and expand from there as needed. Recursion is the key, the following can help you get started:

    open Microsoft.FSharp.Quotations
    open System.Reflection
    
    let rec eval expr =
        match expr with
        | Patterns.Value(value,_) -> value //value
        | Patterns.PropertyGet(Some(instance), pi, args) -> //instance property get
            pi.GetValue(eval instance, evalAll args) //notice recursive eval of instance expression and arg expressions
        | Patterns.PropertyGet(None, pi, args) -> //static property get
            pi.GetValue(null, evalAll args)
        | Patterns.Call(Some(instance), mi, args) -> //instance call
            mi.Invoke(eval instance, evalAll args)
        | Patterns.Call(None, mi, args) -> //static call
            mi.Invoke(null, evalAll args)
        | _ -> failwith "invalid expression"
    and evalAll exprs =
        exprs |> Seq.map eval |> Seq.toArray
    

    And then wrapping this in an Active Pattern will improve syntax:

    let (|Eval|) expr =
        eval expr
    
    match e with 
    | Patterns.Call(_, mi, [Eval(arg1Value); Eval(arg2Value)]) -> ...
    

    Update 2

    OK, this thread got me motivated to try and implement a robust reflection based solution, and I’ve done so with good results which are now part of Unquote as of version 2.0.0.

    It turned out not to be as difficult as I thought it would be, currently I am supporting all quotation expressions except for AddressGet, AddressSet, and NewDelegate. This is already better than PowerPack’s eval, which doesn’t support PropertySet, VarSet, FieldSet, WhileLoop, ForIntegerRangeLoop, and Quote for example.

    Some noteworthy implementation details are with VarSet and VarGet, where I need to pass around an environment name / variable lookup list to each recursive call. It is really an excellent example of the beauty of functional programming with immutable data-structures.

    Also noteworthy is special care taken with issues surrounding exceptions: striping the TargetInvokationExceptions thrown by reflection when it catches exceptions coming from methods it is invoking (this is very important for handling TryWith evaluation properly, and also makes for better user handling of exceptions which fly out of the quotation evaluation.

    Perhaps the most “difficult” implementation detail, or really the most grueling, was the need to implement all of the core operators (well, as most I could discover: the numeric and conversion operators, checked versions as well) since most of them are not given dynamic implementations in the F# library (they are implemented using static type tests with no fallback dynamic implementations), but also means a serious performance increase when using these functions.

    Some informal benchmarking I observe performance increases of up to 50 times over PowerPack’s (not pre-compiled) eval.

    I am also confident that my reflection-based solution will be less bug prone then PowerPack’s, simply because it is less complicated than the PowerPack’s approach (not to mention I’ve backed it up with about 150 unit tests, duly fortified by Unquotes additional 200+ unit tests which now is driven by this eval implementation).

    If you want to peek at the source code, the main modules are Evaluation.fs and DynamicOperators.fs (I’ve locked the links into revision 257). Feel free to grab and use the source code for your own purposes, it licensed under Apache License 2.0! Or you could wait a week or so, when I release Unquote 2.0.0 which will include evaluation operators and extensions publicly.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I need to clean up various Word 'smart' characters in user input, including but
We are using XSLT to translate a RIXML file to XML. Our RIXML contains
i want to parse a xhtml file and display in UITableView. what is the
public static bool CheckLogin(string Username, string Password, bool AutoLogin) { bool LoginSuccessful; // Trim

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.