我遇到了“引用”这个术语,我正在尝试找出一些实际应用的例子。每个代码表达式都有AST的能力听起来很棒,但如何在现实生活中使用它呢?
有人知道这样的例子吗?
有人知道这样的例子吗?
F#和Nemerle引用都用于元编程,但方法不同:Nemerle在编译时使用元编程来扩展语言,而F#在运行时使用。
在Nemerle中,引用用于宏内部,以拆解代码并生成新的代码。许多语言本身就是这样实现的。例如,这是一个来自官方库的示例 - 实现when
条件构造的宏。Nemerle没有语句,因此if
必须有else
部分:when
和unless
宏为一个没有then
和else
部分的if
提供了简写。 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# code.. @>
中或者为函数添加一个特殊的属性来完成:[<ReflectedDefinition>]
let foo () =
// body of a function (standard F# code)