The code quotations feature enables you to generate and work with F# code expressions programmatically.
A quoted expression is delimited in such a way that it is not compiled as part of your program, but is compiled into an object that represents an F# expression.
<@
and @>
to delimit the quoted expression.<@@
and @@>
.The following code shows typed and untyped quotations.
open Microsoft.FSharp.Quotations
// A typed code quotation.
let expr1 : Expr<float> = <@ 9.0 * 3.9 + 4.2 @>
// An untyped code quotation.
let expr2 : Expr = <@@ 9.0 * 3.9 + 4.2 @@>
The resulting type of an expression quoted with the typed symbols is Expr<'T>
, where the type parameter has the type of the expression as determined by the F# compiler's type inference algorithm.
Expr
.Raw
property on the typed Expr
class to obtain the untyped Expr
object.To evaluate F# quotations, you must use the F# Quotation Evaluator.
The following example shows how to evaluate F# quotations.
open FSharp.Linq.RuntimeHelpers
let eval q = LeafExpressionConverter.EvaluateQuotation q
let inline negate x = -x
// val inline negate: x: ^a -> ^a when ^a : (static member ( ~- ) : ^a -> ^a)
<@ negate 1.0 @> |> eval
The constraint generated by the inline
function is retained in the code quotation. The negate
function's quoted form can now be evaluated.
The splicing operators enable you to combine literal code quotations with expressions that you have created programmatically or from another code quotation.
%
and %%
operators enable you to add an F# expression object into a code quotation.%
operator to insert a typed expression object into a typed quotation and the %%
operator to insert an untyped expression object into an untyped quotation.If an expr
is an untyped expression of type Expr
, the following code is valid.
<@@ 3 + %%expr @@>
But if expr
is a typed quotation of type Expr<int>
, the following code is valid.
<@ 3 + %expr @>