一流的功能


11

我本周末开始认真看一下Lisp(这意味着我只是在学习Lisp,而不是回到C#中的项目),必须说我喜欢它。我曾涉猎其他功能语言(F#,Haskell,Erlang),但没有感受到Lisp给我的吸引力。

现在,当我继续学习Lisp时,我开始怀疑为什么非功能语言不支持一流的功能。我知道诸如C#之类的语言可以对委托执行类似的操作,并且在某种程度上您可以使用指向C / C ++中的函数的指针,但这是否有理由为什么它永远不会成为这些语言的功能?使函数成为一流有缺点吗?对我来说,它非常有用,所以我迷失了为什么更多的语言(功能范式之外)没有实现它。

[编辑]我很感谢到目前为止的回答。由于已经向我证明许多语言现在都支持一流的功能,因此我将问题重新表述为:为什么语言要花费这么长时间来实现它们?[/编辑]


3
我不同意C#可以做“类似的事情”。我想说它具有用于所有意图和目的的一流功能(这会破坏您的前提)。它有一个函数文本语法,可以充塞功能为变量等
洛根CAPALDO

@Logan-我正在辩论是否包含C#示例,但决定基于此Wikipedia条目。根据条目,没有真正的一等函数,因为“因为必须手动构造保留函数动态状态的对象”。但是,如果那是不正确的说法,我很想知道为什么!(毕竟,我是来这里学习的,不会被自己束缚!)
束缚杰蒂

2
维基百科条目已过时。现代C#提供了适当的lambda。
SK-logic

我认为该段写得不好。似乎在说C ++函子不是一流的,C#委托也不是吗?虽然我可能同意函子的论点,但我不确定是否会赞成C#代表。它还说“(请参阅lambda提升)”,这是关于这些语言支持词法闭包而不是“函数作为值”的声明。您可以拥有一个而没有另一个。即使是这种情况,对于C#来说也不是正确的,它确实具有词法闭包。问题的一部分是“一流功能”可能是一个模糊的术语。
Logan Capaldo

1
@Logan和SK-Logic-感谢您的反馈并保持建设性态度。我还在学习,不被解雇真是太好了,所以我对此表示赞赏。非常感谢您的评论和回答!
杰蒂2011年

Answers:


5

C#,VB.NET,Python,JavaScript,现在甚至C ++ 0x都提供一流的功能。

更新:

实现闭包需要lambda-lifting(拉姆达)运算法则,这对于命令式程序员本来就很陌生。正确的一流函数(包括闭包)至少需要运行时和VM的一些支持。将旧的功能技术应用于命令式世界还花费了一些时间。

而且,最重要的部分-如果没有垃圾回收,那么一流的功能将几乎无法使用。直到最近,才使用Java以及.NET将其引入大规模编程。最初的Java方法是过分简化语言,以使普通程序员无法理解它。NET紧随其后,直到最近才脱离这一方向(恕我直言,这是完全合理和适当的)。

所有这些概念都需要时间来被业界消化。


我已经根据回复编辑了原始问题。
杰蒂2011年

一流的函数!=闭包(对于后者,GC更为必要)。尽管是的,它们是密切相关的,并且您很少(如果有的话)看到它们是分开的。

@delnan,至少没有某种形式的词法闭包,它们在运行时是不可组合的且不可构造的,这对于一流的函数定义是必不可少的。
SK-logic

不可以。您可以禁止引用封闭范围的变量(或在函数创建时复制所引用变量的值-如果算作闭包则为dunno)。结果不是特别有用,但是函数仍然可以在运行时构造而无需关闭,因此您将拥有(奇怪的)一流的函数。

1
@ SK-logic:C ++ 0x使用通常的技巧提供了不带垃圾回收的闭包->如果变量超出范围,并且您仍然坚持引用,则使用引用是未定义的行为。因此有可能……这只是给开发人员带来了荣誉。
Matthieu M.

5

没有闭包,一流的功能就没那么有趣了。

没有某种范围的动态管理(垃圾回收),关闭是不可能的。使C / C ++如此高性能的原因之一是,在您手动管理内存的语言上编译要容易得多,因此可以使C / C ++摆脱困境。

然后是的,这涉及到面向对象操作的影响。您不再需要将方法和属性分开。方法本身就是接受函数作为值的属性。在这种情况下,重载方法的真正含义是什么,因为您可以随时替换掉那些愚蠢的东西。例如,您是否可以将其真正添加到Java中,而无需对整个语言进行重大的范式转换?人们知道该结构保证每次都将始终以相同的方式工作,那么合同或那种(IMO错误)安全感又在哪里呢?将与对象相关的函数作为方法视为一种不同的有机体,这在语言中可能是有意义的,这些语言最初允许函数独立存在,但是在Java中,这并不是真正的选择。

在JavaScript中,OOP和功能非常紧密地交织在一起,我个人很难将一流的功能看作是固定的功能,只是用其他语言无法实现的功能。但是,这还需要进行其他一些范式转换更改,包括对象及其方法本身的高度可变性,以及能够像调用任何对象一样调用函数。

语言不仅是充满do-hickey的工具集,而且可以使大部分事情完成。他们是范例。各种想法,策略和意见,它们以相互联系(或看起来相互联系)的方式组合在一起。在许多情况下,用作名词和动词的功能实际上根本不适合该范式,或者充其量是不完美的。

话虽如此,当我被迫在没有它们的情况下进行编码时,我感觉自己好像丢失了一条手臂。


您可以将所有方法都视为密封方法,也可以只密封最关心的方法,这样就可以了。
阿列克谢·阿维琴科

@AlexeiAverchenko我很高兴地说我不是100%确定您的意思。抱歉,我错过了您的评论,直到现在。谷歌搜索“密封方法”。
Erik Reppen 2013年

4

这不是真的不可能。但这是另一个功能,并且复杂性预算有限。语言设计者可能认为它是不必要的(或什至不会出现)-“为什么我们需要传递函数?这种语言是用于OS编程的!”。与其他语言合并可能还需要花费大量精力。例如,一个函数类型可能需要对类型系统进行严格的添加(例如,在Java中),如果您有重载的话,甚至还要更多(感谢@Renesis指出这一点)。您还需要提供一些库代码来利用可行的代码-没有人愿意定义map自己。

这也可能使该语言的其他目标难以实现:

  • 优化变得“困难”(在许多情况下实际上并不困难,但是需要的方法与您习惯的方法不同)。例如,如果可以重新分配全局功能,则必须证明f联之前从未重新分配。
  • 同样,如果使函数成为全功能对象,则需要智能编译器和JIT来消除与之相关的开销,并使调用变得高效(速度像推参数和返回地址空间),并跳转到一些地址。
  • 如前所述,这是另一个完整功能,也是支持另一种范式的第一步-如果您想要一种简单的语言,也许您负担不起在不抛出其他东西的情况下添加一流的功能(您可能会认为这很重要)出来。
  • 也许它根本无法与其他语言很好地融合在一起。如果您将语言设计为例如自Smalltalk以来最好的OOP化身,则您可能需要专注于此,而不是提供另一种非常不同的范例。特别是如果很难将两者整合在一起(请参见上文)。良好完成的N个范例比不良执行的N + 1个范例更易于编程。

同样,人们可以问为什么任何一种编程语言L1都没有完全不同的语言L2的特征F。


1

我认为第一个问题是误解,即不能将面向对象和功能混合在一起。至少由Wikipedia描述的语言的快速列表,包括:JavaScriptActionScriptPythonC#F#

第二个问题似乎是对一流函数的定义-例如,为什么不考虑使用C#来拥有它们呢?

我不是函数语言专家,所以如果我错了,请在评论中纠正我,但是我的理解是,一流函数本身的包含或多或少定义了一种语言是否支持函数范式

真正的问题是什么?

因此,理解面向对象的语言可以也可以运作的,这些语言都包含一流的功能,它听起来就像你正在寻找的是一个问题,为什么有些面向对象的语言不包含一流的功能呢?

函数重载

造成这种情况的主要原因之一是,当语言也选择支持函数重载时(例如Java),很难定义一流的函数:

public int dispatchEvent(Event event);
public int dispatchEvent(String event, Object data);

哪一个 dispatchEvent变量将引用函数?

基于类的编程

基于类的编程不会阻止语言支持一流的对象,但是会使它更加混乱或增加要回答的问题。

例如,作为ECMAScript语言的ActionScript始于功能更强大的范例,例如JavaScript。函数并不是天生就绑定到对象上的,实际上,它们可以在执行时用任何对象调用,因为它的作用域是对象。

当您添加(非动态)类时,您将具有固有地绑定到实例的功能,而不仅仅是类本身。Function.apply坦白地说,这使我感到有些皱纹,但我还没有弄清楚它们是如何处理的。


3
“一流的功能本身或多或少使语言具有功能性。” 错了 是前提,是的。但是还有更多的功能,例如(仅举三例)避免了可变状态,着重于表达式和函数应用程序而不是顺序语句以及着重引用透明性。

@delnan那时您应该去正确的Wikipedia ...除非“功能语言”和“支持功能范例的语言”是两回事。
妮可

1
@Rensis:他们是不同的东西。您可以在C语言中创建类似于对象(甚至包括vtables)的对象,但效果并不理想。从“具有一流的功能”转变为“是一种功能性语言”虽然还不错,但是仍然有所不同。此外,Wiki(正确)在链接到的页面上指出“这些功能对于功能编程风格是必要的。” (即:不是“定义功能”),并在FP页面上列出了其他几个功能。

@delnan,好的,我更正了我的措辞。我只是想说一种语言被视为支持功能范例的条件-正如我列出的每种语言的Wikipedia页面一样。我并不是说这就是函数式编程风格的一部分。
妮可

0

我自己也想知道同样的事情。一旦我掌握了lambda的语言,便可以使用很多。当您意识到可以使用php 5.3进行闭包时,即使PHP也会变得更好(它不如lisp好,但仍然更好)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.