【问题标题】:F# Type Providers vs. Lisp macrosF# 类型提供程序与 Lisp 宏
【发布时间】:2012-08-20 09:56:55
【问题描述】:

我一直在阅读有关 F# 3.0 类型提供程序(例如 here)的信息,它们似乎基于一种编译时代码生成。在这方面,我想知道它们如何与 Lisp 宏进行比较。似乎 F# 3.0 类型提供程序和 Lisp 宏都允许用户代码在编译时执行,并引入编译器可用的新类型。任何人都可以阐明所涉及的问题和细微差别吗?

【问题讨论】:

    标签: f# macros lisp metaprogramming type-providers


    【解决方案1】:

    我不熟悉 Lisp 宏,但宏通常用于元编程(以节省输入并为语言添加控制结构)。另一方面,类型提供程序为外部数据源生成强类型 API。

    除了编译时“扩展”之外,我想不出它们有什么共同点。

    【讨论】:

      【解决方案2】:

      F# 类型提供程序和其他语言的元编程技术之间存在一些重叠,但我同意 Daniel 的观点,即它们没有太多共同点。 F# 还有一些其他元编程技术,例如可能更接近 LISP 宏的引用。

      特别是:

      • LISP 宏通常用于转换表达式(您可以获取 LISP 表达式并对其进行解释或转换然后执行它)。请注意,转换采用 LISP 表达式作为输入 - 另一方面,类型提供程序只能采用非常有限的参数(字符串、整数)。

      • 引用更相似。它们可用于处理 F# 表达式 - 您可以将一段 F# 代码视为数据并对其进行解释或转换。转换采用 F# 表达式(的子集),但通常不执行它。

      • 类型提供程序纯粹用于生成类型。由于 LISP 是动态类型的,所以这并不是您在 LISP 中遇到的问题。然而,它是一种代码生成(一种元编程形式,您当然可以在 LISP 中完成)。

      【讨论】:

      • 似乎 Lisp 宏相对于引号的最大优势是编译时执行。 F# 没有这样的东西,不是吗?
      • @Daniel - 我猜类型提供者 (TP) 和引号 (Q) 是宏的两个极端。 Q 允许表达式操作,但不支持编译时执行。 TP 不支持表达式操作,但支持编译时执行(导致生成类型)。
      • 但是,LISP 宏不支持 compile-time 执行,它们在 run-time 进行评估,但是使用动态类型会容易得多。
      • @TomasPetricek:LISP 宏确实允许编译时执行。基本上,当宏展开时,您可以执行任何代码,即您可以使用整个语言。例如,可以在代码中嵌入“编译日期时间”
      • @TomasPetricek,什么? Lisp 宏仅在编译时执行,除非您在运行时编译某些东西。并且键入完全与宏扩展无关(参见 Nemerle、MetaOCaml 甚至 Template Haskell 示例)。
      【解决方案3】:

      F# 类型提供程序的一个有趣方面是它们不仅在编译时工作,而且在设计时 工作,也就是说,以与完整 IDE 工具交互的方式工作。类型提供程序提供来自外部模式化数据源的“类型”,但实现机制还支持许多 IDE 工具,包括 IntelliSense(标识符自动完成)、文档、数据工具提示等。结合交互式 REPL,这提供了简单的探索以一种与任何其他语言都不太一样的方式来处理不熟悉的数据集。

      【讨论】:

      • 嗯。宏也这样做。如果您定义一个宏,您的 Lisp IDE 可以为您提供有关它的智能感知和参数提示,以及向您展示中间扩展。文档也仍然有效。并不是说它不酷,而是问题中vs. 的双方都可以使用它。
      • @Inaimathi:指向这样一个 IDE 的指针?我有兴趣尝试一下 - 到目前为止,我正在以最简单的方式进行 LISP(编辑、通过 slime 发送到 repl、运行)。
      • @ttsidoras - Emacs+SLIME 会在您加载系统时为您提供有关 minibuffer 的提示。我有理由确定 LispWorks 做了类似的事情,但我不使用它。
      【解决方案4】:

      F# 类型提供程序是编译时代码生成的一种非常特殊的情况,即它们旨在通过编译时代码生成来解决特定类型的问题。它们允许您在编译时生成新类型。

      LISP 宏是一种更通用的元编程方法,因此可以满足很多用例。宏基本上将输入作为 S 表达式(代码或数据)并发出其他 S 表达式。

      因此可以使用宏轻松实现类型提供程序,而使用类型提供程序无法涵盖“宏可以做什么”的全部范围。

      【讨论】:

      • “可以使用宏轻松实现类型提供程序” - 它可能没有那么简单和直接。我认为会有一些有趣的问题: 1.) 类型提供程序在调用者代码访问它们时按需生成类型。这对于宏(?)可能是可行的,但它不再是expr -> expr 转换 2。)类型提供程序不仅仅是编译器功能。 IDE 体验是不可或缺的一部分,它依赖于类型,我不确定它在 LISP 世界中是否有直接等价物(同样,这在某些方面是可行的,但可能不太容易)
      • @TomasPetricek:类型提供程序在静态类型语言中更有意义,而在像 Lisp 这样的动态类型语言中则不然。在 Lisp 中,创建 function providers 是有意义的,即为调用远程 Web 服务的代理函数创建 Lisp 代码的宏。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多