Juliet
Juliet

Reputation: 81536

Evaluate Quoted Expression in F#

I hope I haven't missed something obvious, but I've been playing with F# expressions and I want to evaluate quoted expressions on the fly. For example, I want write something like this:

let x = <@ 2 * 5 @>
let y = transform x // replaces op_Multiply with op_Addition, or <@ 2 + 5 @>
let z = eval y // dynamically evaluates y, returns 7

Is there a built-in F# method which can evaluate quoted expressions, or do I have to write my own?

Upvotes: 13

Views: 3527

Answers (5)

Overlord Zurg
Overlord Zurg

Reputation: 3804

Updated in 2016

The Evaluate extension method can now be found in NuGet package FSharp.Quotations.Evaluator

#r "../packages/FSharp.Quotations.Evaluator.1.0.7/lib/net40/FSharp.Quotations.Evaluator.dll"

open FSharp.Quotations.Evaluator

let f = <@ 2 + 3 @>
f.Evaluate()

Upvotes: 7

Stephen Swensen
Stephen Swensen

Reputation: 22307

I've implemented a reflection-based Quotation evaluator as part of Unquote (this is a new feature as of version 2.0.0).

> #r @"..\packages\Unquote.2.2.2\lib\net40\Unquote.dll"

--> Referenced '..\packages\Unquote.2.2.2\lib\net40\Unquote.dll'

> Swensen.Unquote.Operators.eval <@ sprintf "%A" (1,2) @>;;
val it : string = "(1, 2)"

I've measured it to be up to 50 times faster than PowerPack's evaluator. This will, of course, vary by scenario. But Unquote is generally magnitudes faster than PowerPack at interpreting expressions.

It also supports many more expressions than PowerPack's evaluator, including VarSet, PropertySet, FieldSet, WhileLoop, ForIntegerRangeLoop, and Quote. In fact, Unquote's evaluator supports all quotation expressions except NewDelegate, AddressSet, and AddressOf all of which I plan on eventually supporting.

Upvotes: 18

J D
J D

Reputation: 48707

You can evaluate an F# quotation using the Eval extension member provided by the FSharp.PowerPack.Linq DLL as follows:

#r "FSharp.PowerPack.Linq.dll"

open Linq.QuotationEvaluation
let f = <@2 + 3@>
f.Eval()

Note that you must open the Linq.QuotationEvaluation namespace to make this extension member available.

There is also a Compile extension member that returns a suspension but it does not appear to improve performance.

Upvotes: 8

MichaelGG
MichaelGG

Reputation: 10006

No, there's no built-in way to compile F# quotations. With the PowerPack LINQ you can convert SOME quotations to .NET System.Linq.Expressions.Expression, and use that to compile them.

Quotations were made to allow other interpretations of code, such as targeting SQL or a GPU card.

However, in posts on hubfs, it's been hinted at that this is a common request and will be looked at.

Upvotes: 9

Dario
Dario

Reputation: 230

I think the quotations has got a .eval()-method.

Upvotes: -1

Related Questions