制限事項
このライブラリにはいくつかの制限事項があります。
未実装機能
ForIntegerRangeLoop
LetRecursive
NewDelegate
WhileLoop
未サポート機能
AddressOf
AddressSet
Quote
技術的な問題
インライン関数
NoDynamicInvocationAttribute
付きの他のインライン関数を含むインライン関数は起動できません。
例えば、次のコードはSystem.NotSupportedException
を投げます。
1: 2: 3: 4: 5: 6: 7: |
// (-)はNoDynamicInvocationAttribute付き let inline f1 x y = x - y try let expr = <@ f1 20 10 @> expr.Execute() |> ignore with :? System.NotSupportedException -> printfn "raised exception." |
もちろん、NoDynamicInvocationAttribute
付きの関数もこのライブラリでは実行できません。
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." |
もしNoDynamicInvocationAttribute
付きの関数を実行したい場合、
inline
を取るか、手動でインライン化する必要があります。
1: 2: |
let expr = <@ 20 - 10 @> printfn "20 - 10 = %d" (expr.Execute()) |
他にも、メンバー制約起動式を含むインライン関数をこのライブラリで実行することはできません。 これに関する回避策はありません。
mutableとtry-with/try-finally
try-with
とtry-finally
は値を持つ式なので、このライブラリではこれらをラムダ式にラップします。
1: 2: 3: 4: 5: 6: |
let tryWithExpr = <@ let x = 10 let res = try x with _ -> 20 res * 2 @> let compiledTryWithExpr = tryWithExpr.Compile() |
これは以下のようにコンパイルされます。
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 |
x
はラムダを表すクラスのフィールドとしてコンパイルされます。
そのため、ラムダ式の本体でx
を書き換えても、ラムダ式の外側には影響を与えることが出来ません。
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() |
これは、以下のようにコンパイルされます。
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: |
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() // ラムダ式の起動後に代入すべきだが、現在の実装ではそうなっていない。 // y <- tmp.y (y, res2) |
Expr.Value
リテラルを持たない型のExpr.Value
はサポートされていません。
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 "%s" e.Message |
|
Expr.Value
の代わりに、引用式を使ってください。
1:
|
let codeQuote = <@ System.DateTime.UtcNow @> |
1:
|
printfn "%A" (codeQuote.Execute()) |
上の引用式はExpr.Value
にならず、Expr.PropertyGet
になるため、正しく実行できます。
|
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Quotations
namespace FSharp
namespace FSharp.Quotations
namespace FSharp.Quotations.Compiler
val f1 : x:'a -> y:'b -> 'c (requires member ( - ))
Full name: Limitations.f1
Full name: Limitations.f1
val x : 'a (requires member ( - ))
val y : 'b (requires member ( - ))
val expr : Expr<int>
member Expr.Execute : unit -> 'T
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
Full name: Microsoft.FSharp.Core.Operators.ignore
namespace System
Multiple items
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
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
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
Multiple items
type NoDynamicInvocationAttribute =
inherit Attribute
new : unit -> NoDynamicInvocationAttribute
Full name: Microsoft.FSharp.Core.NoDynamicInvocationAttribute
--------------------
new : unit -> NoDynamicInvocationAttribute
type NoDynamicInvocationAttribute =
inherit Attribute
new : unit -> NoDynamicInvocationAttribute
Full name: Microsoft.FSharp.Core.NoDynamicInvocationAttribute
--------------------
new : unit -> NoDynamicInvocationAttribute
val f2 : x:'a -> 'a
Full name: Limitations.f2
Full name: Limitations.f2
val x : 'a
val expr : Expr<int>
Full name: Limitations.expr
Full name: Limitations.expr
val tryWithExpr : Expr<int>
Full name: Limitations.tryWithExpr
Full name: Limitations.tryWithExpr
val x : int
val res : int
val compiledTryWithExpr : ICompiledCode<int>
Full name: Limitations.compiledTryWithExpr
Full name: Limitations.compiledTryWithExpr
member Expr.Compile : unit -> ICompiledCode<'T>
Multiple items
type lambda0 =
inherit FSharpFunc<unit,int>
new : x:int -> lambda0
override Invoke : unit -> int
Full name: Limitations.lambda0
--------------------
new : x:int -> lambda0
type lambda0 =
inherit FSharpFunc<unit,int>
new : x:int -> lambda0
override Invoke : unit -> int
Full name: Limitations.lambda0
--------------------
new : x:int -> lambda0
new : unit -> FSharpFunc<'T,'U>
type unit = Unit
Full name: Microsoft.FSharp.Core.unit
Full name: Microsoft.FSharp.Core.unit
Multiple items
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<_>
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<_>
override lambda0.Invoke : unit -> int
Full name: Limitations.lambda0.Invoke
Full name: Limitations.lambda0.Invoke
val x : int
Full name: Limitations.x
Full name: Limitations.x
val res : int
Full name: Limitations.res
Full name: Limitations.res
val letMutableAndTryWithExpr : Expr<int * int>
Full name: Limitations.letMutableAndTryWithExpr
Full name: Limitations.letMutableAndTryWithExpr
val mutable y : int
val res2 : int
val compiledLetMutableAndTryWithExpr : ICompiledCode<int * int>
Full name: Limitations.compiledLetMutableAndTryWithExpr
Full name: Limitations.compiledLetMutableAndTryWithExpr
Multiple items
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
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
val y : int
member lambda1.y : int
Full name: Limitations.lambda1.y
Full name: Limitations.lambda1.y
val set : elements:seq<'T> -> Set<'T> (requires comparison)
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set
val this : lambda1
override lambda1.Invoke : unit -> int
Full name: Limitations.lambda1.Invoke
Full name: Limitations.lambda1.Invoke
property lambda1.y: int
val mutable y : int
Full name: Limitations.y
Full name: Limitations.y
val tmp : lambda1
Full name: Limitations.tmp
Full name: Limitations.tmp
val res2 : int
Full name: Limitations.res2
Full name: Limitations.res2
override lambda1.Invoke : unit -> int
val valueExpr : Expr<System.DateTime>
Full name: Limitations.valueExpr
Full name: Limitations.valueExpr
Multiple items
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 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<_>
Multiple items
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)
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:'T -> Expr
static member Expr.Value : value:obj * expressionType:System.Type -> Expr
static member Expr.Value : value:obj * expressionType:System.Type -> Expr
property System.DateTime.UtcNow: System.DateTime
static member Expr.Cast : source:Expr -> Expr<'T>
val e : exn
property System.Exception.Message: string
val codeQuote : Expr<System.DateTime>
Full name: Limitations.codeQuote
Full name: Limitations.codeQuote