繁体   English   中英

报价真实用法

[英]Quotation real usages

我面对的是“引用”一词,我试图弄清楚一些现实生活中使用它的例子。 为每个代码表达式设置AST的能力听起来很棒,但如何在现实生活中使用它?

有谁知道这样的例子?

F#和Nemerle引用都用于元编程,但方法不同:Nemerle在编译时使用元编程来扩展语言,而F#在运行时使用它们。

Nemerle

在Nemerle中,在宏中使用引号来分离代码片段并生成新代码。 大多数语言本身都是以这种方式实现的。 例如,以下是官方库中的一个示例 - 实现when条件构造的宏。 Nemerle没有发言,所以一个if都必须有一个else部分: whenunless宏的速记提供if用一个空thenelse部件,分别。 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模式x is y when z它是否跟随x is y when z并给出构成它的表达式。 如果匹配成功,我们可以从我们使用的部分生成一个新表达式:

<[
    match ($subCond)
    {
    | $pattern when $guard => $body : void
    | _ => ()
    }
]>

这将when (x is y when z) body转换为基本模式匹配表达式。 所有这些都是自动类型安全的,并且在错误使用时会产生合理的编译错误。 因此,正如您所看到的,引用提供了一种非常方便且类型安全的操作代码的方法。

好吧,无论何时你想以编程方式操作代码,或者做一些元编程,引用都会使它更具说明性 ,这是一件好事

我写了两篇关于如何让Nemerle生活更轻松的帖子: 这里这里

对于现实生活中的例子,有趣的是,Nemerle本身将许多常见语句定义为宏(使用引号)。 一些例子包括: ifforforeachwhilebreakcontinueusing

我认为引用在F#和Nemerle中的用途完全不同。 在F#中,您不使用引号来扩展F#语言本身,而是使用它们来获取用标准F#编写的某些程序的AST(代码的数据表示)。

在F#中,这可以通过在<@ ..F# code.. @>包装一段代码,或者通过向函数添加特殊的attribtue来完​​成:

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

Robert已经提到了这种机制的一些用法 - 您可以获取代码并将F#转换为SQL以查询数据库 ,但还有其他一些用途。 你可以举例如:

正如Jordão已经提到的,引用已启用元编程。 一个真实世界的例子就是能够使用引号将F#翻译成另一种语言,例如SQL。 通过这种方式,Quotations服务器与表达式树在C#中的作用大致相同:它们使linq查询能够转换为SQL(或其他数据访问语言)并针对数据存储执行。

Unquote是报价用法的真实例子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM