Limitations
This library has some limitations.
Not Implemented Yet
ForIntegerRangeLoop
LetRecursive
NewDelegate
WhileLoop
Unupported
AddressOf
AddressSet
Quote
Technical Problem
inline function
The inline functions that contains other inline function with NoDynamicInvocationAttribute
can not invoke.
For example, the following code throws System.NotSupportedException
.
1: 2: 3: 4: 5: 6: 7: |
// (-) has NoDynamicInvocationAttribute. let inline f1 x y = x - y try let expr = <@ f1 20 10 @> expr.Execute() |> ignore with :? System.NotSupportedException -> printfn "raised exception." |
Of course, the inline function with NoDynamicInvocationAttribute
can not execute using this library.
1: 2: 3: 4: 5: 6: 7: |
[<NoDynamicInvocationAttribute >] let inline f2 x = x try let expr = <@ f2 10 @> expr.Execute() |> ignore with :? System.NotSupportedException -> printfn "raised exception." |
If you want to execute the function that contains other inline function with NoDynamicInvocationAttribute
,
you need to remove inline
or to inline by hand.
1: 2: |
let expr = <@ 20 - 10 @> printfn "20 - 10 = %d" (expr.Execute()) |
In other case, the inline functions that contains member constraint invocation expressions can not also execute by this library. There is no workarround.
mutable and try-with/try-finally
This library wraps try-with
and try-finally
in the lambda expression because they are expression that has the value.
1: 2: 3: 4: 5: 6: |
let tryWithExpr = <@ let x = 10 let res = try x with _ -> 20 res * 2 @> let compiledTryWithExpr = tryWithExpr.Compile() |
It is compiled as following.
1: 2: 3: 4: 5: 6: 7: 8: 9: |
type lambda0(x) = inherit FSharpFunc<unit, int>() override __.Invoke(_) = try x with _ -> 20 let x = 10 let res = lambda0(x).Invoke() res * 2 |
The x
is compiled to the field of the lambda class.
So rewrite the x
in the body of the lambda expression, it does not affect the outside of the lambda expression.
1: 2: 3: 4: 5: 6: |
let letMutableAndTryWithExpr = <@ let mutable y = 0 let res2 = try y <- 10; y with _ -> 20 (y, res2) @> let compiledLetMutableAndTryWithExpr = letMutableAndTryWithExpr.Compile() |
It is compiled as following.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: |
type lambda1(y) = inherit FSharpFunc<unit, int>() member val y = y with get, set override this.Invoke(_) = try this.y <- 10; y with _ -> 20 let mutable y = 0 let tmp = lambda1(y) let res2 = tmp.Invoke() // should assign after invocation of the lambda expression. // But now implementation does not assign. // y <- tmp.y (y, res2) |
Expr.Value
The Expr.Value
is not supported the type that does not have the literal.
1: 2: 3: |
let valueExpr: Expr<System.DateTime> = Expr.Value(System.DateTime.UtcNow) |> Expr.Cast |
1: 2: 3: 4: |
try valueExpr.Execute() |> ignore with e -> printfn "%A" e.Message |
|
You should use the quoted expression instead of using the Expr.Value
.
1:
|
let codeQuote = <@ System.DateTime.UtcNow @> |
1:
|
printfn "%A" (codeQuote.Execute()) |
The above quoted expression can execute as expected
because it is evaluated as Expr.PropertyGet
rather than Expr.Value
.
|
Full name: Limitations.f1
Full name: Microsoft.FSharp.Core.Operators.ignore
type NotSupportedException =
inherit SystemException
new : unit -> NotSupportedException + 2 overloads
Full name: System.NotSupportedException
--------------------
System.NotSupportedException() : unit
System.NotSupportedException(message: string) : unit
System.NotSupportedException(message: string, innerException: exn) : unit
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
type NoDynamicInvocationAttribute =
inherit Attribute
new : unit -> NoDynamicInvocationAttribute
Full name: Microsoft.FSharp.Core.NoDynamicInvocationAttribute
--------------------
new : unit -> NoDynamicInvocationAttribute
Full name: Limitations.f2
Full name: Limitations.expr
Full name: Limitations.tryWithExpr
Full name: Limitations.compiledTryWithExpr
type lambda0 =
inherit FSharpFunc<unit,int>
new : x:int -> lambda0
override Invoke : unit -> int
Full name: Limitations.lambda0
--------------------
new : x:int -> lambda0
Full name: Microsoft.FSharp.Core.unit
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
Full name: Limitations.lambda0.Invoke
Full name: Limitations.x
Full name: Limitations.res
Full name: Limitations.letMutableAndTryWithExpr
Full name: Limitations.compiledLetMutableAndTryWithExpr
type lambda1 =
inherit FSharpFunc<unit,int>
new : y:int -> lambda1
override Invoke : unit -> int
member y : int
member y : int with set
Full name: Limitations.lambda1
--------------------
new : y:int -> lambda1
Full name: Limitations.lambda1.y
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set
Full name: Limitations.lambda1.Invoke
Full name: Limitations.y
Full name: Limitations.tmp
Full name: Limitations.res2
Full name: Limitations.valueExpr
type Expr =
override Equals : obj:obj -> bool
member GetFreeVars : unit -> seq<Var>
member Substitute : substitution:(Var -> Expr option) -> Expr
member ToString : full:bool -> string
member CustomAttributes : Expr list
member Type : Type
static member AddressOf : target:Expr -> Expr
static member AddressSet : target:Expr * value:Expr -> Expr
static member Application : functionExpr:Expr * argument:Expr -> Expr
static member Applications : functionExpr:Expr * arguments:Expr list list -> Expr
...
Full name: Microsoft.FSharp.Quotations.Expr
--------------------
type Expr<'T> =
inherit Expr
member Raw : Expr
Full name: Microsoft.FSharp.Quotations.Expr<_>
type DateTime =
struct
new : ticks:int64 -> DateTime + 10 overloads
member Add : value:TimeSpan -> DateTime
member AddDays : value:float -> DateTime
member AddHours : value:float -> DateTime
member AddMilliseconds : value:float -> DateTime
member AddMinutes : value:float -> DateTime
member AddMonths : months:int -> DateTime
member AddSeconds : value:float -> DateTime
member AddTicks : value:int64 -> DateTime
member AddYears : value:int -> DateTime
...
end
Full name: System.DateTime
--------------------
System.DateTime()
(+0 other overloads)
System.DateTime(ticks: int64) : unit
(+0 other overloads)
System.DateTime(ticks: int64, kind: System.DateTimeKind) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, calendar: System.Globalization.Calendar) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: System.DateTimeKind) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: System.Globalization.Calendar) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: System.DateTimeKind) : unit
(+0 other overloads)
static member Expr.Value : value:obj * expressionType:System.Type -> Expr
Full name: Limitations.codeQuote