哪种语言习语/范例/功能使得难以添加对“类型提供者”的支持?

时间:2011-09-15 09:15:45

标签: c# database f# clr language-design

F#3.0添加了type providers

我想知道是否可以将此语言功能添加到CLR上运行的其他语言(如C#),或者此功能是否仅适用于功能更少/更少OO编程风格?

3 个答案:

答案 0 :(得分:8)

正如Tomas所说,在任何静态类型的语言中添加这种功能在理论上都是直截了当的(虽然仍然有很多笨拙的工作)。

我不是元编程专家,但@ SK-logic问为什么不是一般的编译时元编程系统,我将尝试回答。我不认为您可以使用元编程轻松实现使用F#类型提供程序所能做的事情,因为F#类型提供程序在设计时可以是惰性和动态交互的。让我们举一个Don在他之前的一个视频中演示过的例子:一个Freebase类型的提供者。 Freebase有点像一个模式化的可编程维基百科,它包含所有内容的数据。所以你最终可以按照

的方式编写代码
for e in Freebase.Science.``Chemical Elements`` do
    printfn "%d: %s - %s" e.``Atomic number`` e.Name e.Discoverer.Name

或诸如此类(我没有准确的代码),但同样容易编写获取有关棒球统计信息的代码,或者当着名演员已经进入戒毒所,或通过其他方式提供的其他类型的信息时游离碱。

从实现的角度来看,为所有Freebase生成一个模式并将其带入.NET-priori是不可行的。你不能只是在开始时做一个编译时步骤来设置所有这些。您可以为小型数据源执行此操作,实际上许多其他类型的提供程序都使用此策略,例如: SQL类型提供程序指向数据库,并为该数据库中的所有类型生成.NET类型。但是这个策略对Freebase这样的大型云数据存储工作,因为有太多相互关联的类型(如果你试图为所有Freebase生成.NET元数据,你会发现有这样的数百万种类型(其中一种类型ChemicalElement包含AtomicNumberDiscoverer以及Name以及许多其他字段,但实际上有数百万种此类类型需要更多内存比32位.NET进程可用的内存只是为了表示整个类型模式。

因此,F#类型提供程序策略是一种API体系结构,允许类型提供程序按需提供信息,在IDE内的设计时运行。直到您输入例如Freebase.Science.,类型提供者不需要知道科学类别下的实体,但是一旦你在.之后按Science,那么类型提供者可以去查询API学习整体模式的一个更多层次,了解“科学”下存在哪些类别,其中一个是ChemicalElements。然后当你试图“插入”其中一个时,它会发现元素具有原子序数和什么不是。因此,类型提供程序懒洋洋地提取整个模式,以处理用户恰好在该时刻输入编辑器的确切代码。因此,用户仍然可以自由地探索信息世界的任何部分,但任何一个源代码文件或交互式会话将只探索可用内容的一小部分。当编译/ codegen时,编译器只需生成足够的代码来完全容纳用户在其代码中实际使用的位,而不是潜在的巨大运行时位,以提供与整个数据存储通信的可能性。

(也许你现在可以用现在的一些元编程设施做到这一点,我不知道,但我在学校学到的很长一段时间都不能轻易解决这个问题。)

答案 1 :(得分:7)

正如Brian和Tomas所指出的那样,这个功能并没有特别“功能”。这只是向编译器提供元数据的一种特别灵活的方式。

C#设计团队长期以来一直在围绕这样的想法。在我加入C#团队之前几年提出了一项建议,该功能将被称为“类型蓝图”(或类似的东西),其中XML文档,XML模式和提供类型元数据的自定义代码的组合可以由C#编译器使用。我不记得细节,显然它从未实现过。 (虽然它确实影响了我当时正在处理的Visual Studio Tools for Office文档格式的设计和实现。)

无论如何,我们没有计划立即向C#添加这样的功能,但我们非常感兴趣地看着它是否能很好地解决F#中的客户问题。

(一如既往,Eric关于未公布和完全假设产品可能的未来特征的思考仅用于娱乐目的。)

答案 2 :(得分:5)

我认为没有任何技术原因可以将类型提供程序之类的内容添加到C#或类似语言中。唯一一个难以添加类型提供程序的语言(以与F#类似的方式)是动态类型语言

F#类型提供程序依赖于这样一个事实,即提供程序生成的类型信息很好地传播通过程序,编辑器可以使用它们来显示有用的IntelliSense。在动态类型语言中,这需要更复杂的IDE支持(动态语言的“类型提供程序”只需要IDE或IntelliSense)。

为什么它们直接作为F#的功能实现?我认为元编程系统必须非常复杂(请注意,类型不是实际生成的)以支持这一点。使用它可以完成的其他事情对F#语言的贡献不大(它们只会使它过于复杂,这是一件坏事)。但是,如果你有某种编译器可扩展性,你可能会得到类似的东西。

事实上,我认为这就是C#团队将来会添加类型提供程序的方式(他们现在讨论了编译器的可扩展性)。