Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#类型提供程序与Lisp宏_F#_Macros_Lisp_Metaprogramming_Type Providers - Fatal编程技术网

F#类型提供程序与Lisp宏

F#类型提供程序与Lisp宏,f#,macros,lisp,metaprogramming,type-providers,F#,Macros,Lisp,Metaprogramming,Type Providers,我一直在阅读有关F#3.0类型提供程序(例如)的文章,它们似乎是基于编译时代码生成的。在这方面,我想知道它们与Lisp宏相比如何。似乎F#3.0类型提供程序和Lisp宏都允许用户代码在编译时执行,并引入编译器可用的新类型。有人能解释一下这个问题和其中的细微差别吗?我不熟悉Lisp宏,但宏通常用于元编程(保存键入并向语言中添加控件结构)。另一方面,类型提供程序为外部数据源生成强类型API 除了编译时“扩展”之外,我想不出它们有什么共同之处。在F#type提供程序和其他语言的元编程技术之间有一些重叠

我一直在阅读有关F#3.0类型提供程序(例如)的文章,它们似乎是基于编译时代码生成的。在这方面,我想知道它们与Lisp宏相比如何。似乎F#3.0类型提供程序和Lisp宏都允许用户代码在编译时执行,并引入编译器可用的新类型。有人能解释一下这个问题和其中的细微差别吗?

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


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

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

特别是:

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

  • 报价更相似。它们可以用来处理F#表达式——您可以将一段F#代码作为数据处理,并对其进行解释或转换。转换接受(一个子集)一个F#表达式,但通常不执行它

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

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

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

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


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

似乎Lisp宏相对于引号的最大优势是编译时执行。“F#没有类似的东西,是吗?”@Daniel-我猜类型提供者(TP)和引号(Q)是宏的两个极端方面。Q允许表达式操作,但不支持编译时执行。TP不支持表达式操纵,但支持编译时执行(生成类型)。然而,LISP宏不支持编译时执行,它们在运行时进行计算,但使用动态类型更容易。@TomasPetricek:LISP宏允许编译时执行。基本上,当宏展开时,您可以执行任何代码,即您可以使用整个语言。例如,在代码中嵌入“编译日期时间”可以done@TomasPetricek什么?Lisp宏仅在编译时执行,除非您在运行时编译某些内容。而且键入与宏扩展完全无关(参见Nemerle、MetaOCaml甚至TemplateHaskell的例子)。宏也会这样做。如果定义宏,LispIDE可以为您提供有关宏的智能感知和参数提示,以及显示中间扩展。文档也仍然有效。并不是说它不酷,但它对问题中的
的两面都可用。@Inaimathi:指向这样一个IDE的指针?我有兴趣尝试一下-到目前为止,我正在以最简单的方式使用LISP(编辑,通过slime发送到repl,然后运行)。@ttsidoras-Emacs+slime会在加载系统时提示您使用minibuffer。我相当肯定LispWorks也有类似的功能,但我不使用它。“类型提供程序可以很容易地使用宏实现”——它可能没有那么简单和直接。我认为会有一些有趣的问题:1.)类型提供程序在调用程序代码访问类型时按需生成类型。这对于宏(?)可能是可行的,但它不再是
expr->expr
transformation 2。)类型提供程序不仅仅是编译器功能。IDE体验是不可或缺的一部分,它依赖于类型,我不确定它在LISP世界中是否会有直接的等效性(同样,这在某些方面是可行的,但可能不太容易)@TomasPetricek:类型提供程序在静态类型语言中更有意义,而在像LISP这样的动态类型语言中则没有意义。在Lisp中,创建
函数提供程序
是有意义的,即宏为调用远程web服务的代理函数创建Lisp代码。