引用真实用途

发布于 2024-12-06 07:18:35 字数 95 浏览 5 评论 0原文

我遇到了“引用”一词,我试图找出一些现实生活中使用它的例子。为每个代码表达式提供 AST 的能力听起来很棒,但如何在现实生活中使用它呢?

有谁知道这样的例子吗?

I faced with the 'quotation' term and I'm trying to figure out some real-life examples of usage of it. Ability of having AST for each code expression sounds awesome, but how to use it in real life?

Does anyone know such example?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

各自安好 2024-12-13 07:18:35

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

Nemerle

在 Nemerle 中,宏中使用引号来分解代码片段并生成新代码。语言本身的大部分都是通过这种方式实现的。例如,这里是官方库中的一个示例 - 实现 when 条件构造的宏。 Nemerle 没有语句,因此 if 必须有 else 部分:whenunless 宏提供简写对于分别具有空 thenelse 部分的 ifwhen 宏还具有扩展的模式匹配功能。

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# and Nemerle quotations are both used for metaprogramming, but the approaches are different: Nemerle uses metaprogramming at compilation time to extend the language, while F# uses them at run time.

Nemerle

In Nemerle, quotations are used within macros for taking apart pieces of code and generating new ones. Much of the language itself is implemented this way. For example, here is an example from the official library — the macro implementing the when conditional construct. Nemerle does not have statements, so an if has to have an else part: when and unless macros provide shorthand for an if with an empty then and else parts, respectively. The when macro also has extended pattern-matching functionality.

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 | _ => () } ]>
    }
}

The code uses quotation to handle patterns that look like some predefined templates and replace them with corresponding match expressions. For example, matching the cond expression given to the macro with:

<[ $subCond is $pattern when $guard ]>

checks whether it follows the x is y when z pattern and gives us the expressions composing it. If the match succeeds, we can generate a new expression from the parts we got using:

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

This converts when (x is y when z) body to a basic pattern-matching expression. All of this is automatically type-safe and produces reasonable compilation errors when used incorrectly. So, as you see quotation provides a very convenient and type-safe way of manipulating code.

忆梦 2024-12-13 07:18:35

好吧,每当您想要以编程方式操作代码或进行一些元编程时,引号都会使其更具声明性,这是一件好事。

我写了两篇文章,介绍这如何让 Nemerle 的生活变得更轻松:此处< /a> 和此处

对于现实生活中的示例,有趣的是 Nemerle 本身将许多常见语句定义为宏(其中使用引号)。一些示例包括:ifforforeachwhilebreak、<代码>继续和使用

Well, anytime you want to manipulate code programmatically, or do some metaprogramming, quotations make it more declarative, which is a good thing.

I've written two posts about how this makes life easier in Nemerle: here and here.

For real life examples, it's interesting to note that Nemerle itself defines many common statements as macros (where quotations are used). Some examples include: if, for, foreach, while, break, continue and using.

苦妄 2024-12-13 07:18:35

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

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

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

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

I think quotations have quite different uses in F# and Nemerle. In F#, you don't use quotations to extend the F# language itself, but you use them to take an AST (data representation of code) of some program written in standard F#.

In F#, this is done either by wrapping a piece of code in <@ ..F# code.. @>, or by adding a special attribtue to a function:

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

Robert already mentioned some uses of this mechanism - you can take the code and translate F# to SQL to query database, but there are several other uses. You can for example:

她比我温柔 2024-12-13 07:18:35

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

As Jordão has mentioned already quotations enable meta programming. One real world example of this is the ability to use quotations to translated F# into another language, like for example SQL. In this way Quotations server much the same purpose as expression trees do in C#: they enable linq queries to be translated into SQL (or other data-acess language) and executed against a data store.

甜尕妞 2024-12-13 07:18:35

取消引用是引用使用的真实示例。

Unquote is a real-life example of quotation usage.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文