私は「引用」という用語に直面し、それを実際に使用した例をいくつか見つけようとしています。コード式ごとに AST を使用できるというのは素晴らしいことのように思えますが、実際にはどのように使用すればよいのでしょうか?
誰かそのような例を知っていますか?
私は「引用」という用語に直面し、それを実際に使用した例をいくつか見つけようとしています。コード式ごとに AST を使用できるというのは素晴らしいことのように思えますが、実際にはどのように使用すればよいのでしょうか?
誰かそのような例を知っていますか?
F# と Nemerle の引用符はどちらもメタプログラミングに使用されますが、アプローチは異なります。Nemerle はコンパイル時にメタプログラミングを使用して言語を拡張しますが、F# は実行時にメタプログラミングを使用します。
Nemerle では、コードの断片を分解して新しいコードを生成するために、マクロ内で引用符が使用されます。言語自体の多くは、この方法で実装されています。たとえば、これは公式ライブラリの例です —when
条件付き構造を実装するマクロです。Nemerle にはステートメントがないため、 anif
にはpart が必要else
です: when
andunless
マクロは、それぞれif
空then
とelse
part を持つ an の省略形を提供します。このwhen
マクロには、パターン マッチング機能も拡張されています。
macro whenmacro (cond, body)
syntax ("when", "(", cond, ")", body)
{
match (cond)
{
| <[ $subCond is $pattern ]> with guard = null
| <[ $subCond is $pattern when $guard ]> =>
match (pattern)
{
| PT.PExpr.Call when guard != null =>
// generate expression to replace 'when (expr is call when guard) body'
<[ match ($subCond) { | $pattern when $guard => $body : void | _ => () } ]>
| PT.PExpr.Call =>
// generate expression to replace 'when (expr is call) body'
<[ match ($subCond) { | $pattern => $body : void | _ => () } ]>
| _ =>
// generate expression to replace 'when (expr is pattern) body'
<[ match ($cond) { | true => $body : void | _ => () } ]>
}
| _ =>
// generate expression to replace 'when (cond) body'
<[ match ($cond : bool) { | true => $body : void | _ => () } ]>
}
}
このコードは引用符を使用して、定義済みのテンプレートのようなパターンを処理し、対応するmatch
式に置き換えます。たとえばcond
、マクロに指定された式を次のように一致させます。
<[ $subCond is $pattern when $guard ]>
x is y when z
パターンに従っているかどうかをチェックし、それを構成する式を提供します。一致が成功した場合、使用して得た部分から新しい式を生成できます。
<[
match ($subCond)
{
| $pattern when $guard => $body : void
| _ => ()
}
]>
when (x is y when z) body
これは、基本的なパターン マッチング式に変換されます。これらはすべて自動的にタイプ セーフであり、誤って使用すると妥当なコンパイル エラーが生成されます。ご覧のとおり、クォーテーションは、コードを操作するための非常に便利でタイプ セーフな方法を提供します。
F#とNemerleでは、引用の用途がまったく異なると思います。F#では、引用符を使用してF#言語自体を拡張することはありませんが、引用符を使用して、標準のF#で記述されたプログラムのAST(コードのデータ表現)を取得します。
F#では、これはコードの一部をでラップするか<@ ..F# code.. @>
、関数に特別な属性を追加することによって行われます。
[<ReflectedDefinition>]
let foo () =
// body of a function (standard F# code)
Robertは、このメカニズムのいくつかの使用法についてすでに説明しました。コードを取得してF#をSQLに変換し、データベースにクエリを実行できますが、他にもいくつかの使用法があります。たとえば、次のことができます。
Jordão がすでに述べたように、引用はメタ プログラミングを可能にします。これの実例の 1 つは、引用符を使用して F# を SQL などの別の言語に翻訳する機能です。このように、Quotations サーバーは、C# での式ツリーとほぼ同じ目的を果たします。つまり、linq クエリを SQL (または他のデータ アクセス言語) に変換し、データ ストアに対して実行できるようにします。
Unquoteは引用符の実際の使用例です。