3

私は「引用」という用語に直面し、それを実際に使用した例をいくつか見つけようとしています。コード式ごとに AST を使用できるというのは素晴らしいことのように思えますが、実際にはどのように使用すればよいのでしょうか?

誰かそのような例を知っていますか?

4

5 に答える 5

5

F# と Nemerle の引用符はどちらもメタプログラミングに使用されますが、アプローチは異なります。Nemerle はコンパイル時にメタプログラミングを使用して言語を拡張しますが、F# は実行時にメタプログラミングを使用します。

ネメルレ

Nemerle では、コードの断片を分解して新しいコードを生成するために、マクロ内で引用符が使用されます。言語自体の多くは、この方法で実装されています。たとえば、これは公式ライブラリの例です —when条件付き構造を実装するマクロです。Nemerle にはステートメントがないため、 anifにはpart が必要elseです: whenandunlessマクロは、それぞれifthenelsepart を持つ 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これは、基本的なパターン マッチング式に変換されます。これらはすべて自動的にタイプ セーフであり、誤って使用すると妥当なコンパイル エラーが生成されます。ご覧のとおり、クォーテーションは、コードを操作するための非常に便利でタイプ セーフな方法を提供します。

于 2011-09-24T21:05:07.203 に答える
4

コードをプログラムで操作したり、何らかのメタプログラミングを実行したりする場合はいつでも、引用符を使用するとより宣言的になります。これは良いことです

これが Nemerle での生活をどのように楽にするかについて、私は 2 つの投稿を書きました:ここここ.

実際の例として、Nemerle 自身が多くの一般的なステートメントをマクロ (引用符が使用されている場所) として定義していることに注意してください。例としてはifforforeachwhilebreakcontinueおよびがありusingます。

于 2011-09-23T13:17:21.057 に答える
2

F#とNemerleでは、引用の用途がまったく異なると思います。F#では、引用符を使用してF#言語自体を拡張することはありませんが、引用符を使用して、標準のF#で記述されたプログラムのAST(コードのデータ表現)を取得します。

F#では、これはコードの一部をでラップするか<@ ..F# code.. @>、関数に特別な属性を追加することによって行われます。

[<ReflectedDefinition>]
let foo () = 
  // body of a function (standard F# code)

Robertは、このメカニズムのいくつかの使用法についてすでに説明しました。コードを取得してF#をSQLに変換し、データベースにクエリを実行できますが、他にもいくつかの使用法があります。たとえば、次のことができます。

于 2011-09-23T14:14:33.227 に答える
1

Jordão がすでに述べたように、引用はメタ プログラミングを可能にします。これの実例の 1 つは、引用符を使用して F# を SQL などの別の言語に翻訳する機能です。このように、Quotations サーバーは、C# での式ツリーとほぼ同じ目的を果たします。つまり、linq クエリを SQL (または他のデータ アクセス言語) に変換し、データ ストアに対して実行できるようにします。

于 2011-09-23T14:01:08.437 に答える
1

Unquoteは引用符の実際の使用例です。

于 2011-09-23T19:47:51.700 に答える