LISP和C#在函数式编程方面有哪些主要区别?具体而言,如果LISP程序员转而使用C#,他们最有可能错过的功能是什么?
在C#中进行函数式编程在技术上是可行的(嗯,任何具有函数指针或代理等效的语言都可以"有效") - 但如果你尝试做很多事情,C#会非常痛苦.
在我的头顶,没有特别的顺序:
类型推断
仅适用于当地人
应该适用于几乎所有的东西
我对C#的第一个问题是这个.特别是当你声明一个本地函数时... Func <...> = ouch.
完整的一流功能
代表不是答案,因为它们在结构上不相同.没有规范类型来表示某种类型的函数.例如:什么是"增量"?它是一个功能?它是转换器吗?还有别的吗?这反过来使推理更复杂.
自动泛化
很难计算和指定所有泛型类型参数及其约束
更好地支持不变性
声明简单数据类型变得微不足道
复制修改类型的东西(var x = oldX {SomeField = newVal})
元组 C#7
受歧视的工会(总和类型)
模式匹配 C#7
使元组和总和类型更有价值
允许更多面向表达式的代码
一般monad语法
使异步代码更容易编写 C#5
在嵌套了2层以上的BeginXXX/EndXXX后,它变得非常难看.
功能块的语法很简单,所以你不会得到像"});})这样的结束行;"
编辑:还有一个:
功能构成
现在,做任何类型的功能组合都很痛苦.滚动,链接等LINQ在这里没有受到伤害,因为扩展方法采用第一个参数,如实例方法.
C#也应该发出tail.call.不需要,JIT将根据需要自行添加尾调用.
自写这个答案以来,已经解决了粗体项目.
主要支持不变性.
创建一个不可变类型并验证它是不可变的应该很容易.应该很容易使用不可变类型 - 支持像对象和集合初始化器,但对于不可变的情况.
之后:更好的类型推断功能,元组,模式匹配和支持库(再次,不可变列表等).
编辑:我应该说我不是一个功能程序员,但我是一名C#程序员,试图学习更多功能方法.我目前正在帮助(以一种方式)使用函数式编程书,所以我在那里学到了很多东西.
但是,您希望对LINQ感到满意.它让生活多用于处理数据的序列工作更容易.
如果您要求Lisper而不是ML系列功能程序员,您将不会听到有关元组或推理的任何信息.他们会说一句话,沾沾自喜:MACROS.
根据你的问题,作为一个Lisper,我在Java编程时想念的(抱歉,我不使用C#):
好的语法:s表达式.
动态类型:没有复杂的类型声明.
闭包.
C#地址(2)和(3)分别用var
和=>
,据我所知.因此,我的主要问题是curles和semi-colons,以及冗长,混乱的泛型类型声明.
根据你的标题,作为一个函数式程序员(Haskell),我想念所有其他人所说的:不变性,完整类型推理,元组,模式匹配,更简单的泛型,因为没有子类化,强类型库.
另外,作为Haskell程序员,我仍然不喜欢curlies和semi-colons.:)
为了进一步扩展Jon的观点,我在函数式编程语言中的真正价值不是他们所拥有的,而是他们所缺少的.
现在大多数"大"语言都有(或者可以被欺骗)基本的函数编程原语,如递归,高阶函数等.所以如果你真的想要,你可以用大多数语言编写函数式编程风格(好吧,如果你的C编译器中有尾调用优化,你几乎可以在C中编写函数式代码).
另一方面,主流语言也有很多你在纯函数式编程语言中没有的东西,这些东西可以真正"打破"功能模型,并且无法推理你的功能 - 样式程序的方式与纯函数式语言相同.可变的局部变量和全局变量,围绕可变状态并发(传统的多线程编程)的所有功能,甚至迭代,如果处理不当,都会使您的功能样式代码无法实现(就像它一样).
即使您可能能够限制自己滥用主流编程语言中的功能,但随着时间的推移,每个接触代码的人都不可能克制自己,因此您无法对代码库的功能做出假设.没有真正彻底的代码审查.一些"非功能性"问题也非常微妙,因此想要编写功能代码的人可能会出现问题.
确保功能正常的最佳方法是学习和使用函数式编程语言.我已经设法学习Erlang,以至于我现在正在用非常有限的业余时间编写一个游戏服务器,所以这不是一个很大的挑战 - 我相信功能性编程语言,一旦你换行围绕基本概念,你会更容易学习,因为它们更加简洁.
与Linq(基本上是嵌入在C#中的函数语言,在观看Erik Meijers博士关于Haskell的精彩视频系列时变得更加明显)相结合的一点创造力将允许您使代码看起来更具功能性.
这里是一个不使用Linq的例子:
哈斯克尔:
minThree :: Int -> Int -> Int -> Int minThree x y z | x <= y && x <=z = x | y <=z = y | otherwise = z
C#:
int MinThree(int x, int y, int z) { return x <= y && x <= z ? x : y <= z ? y : z; }
只是不要让Resharper Code Cleanup运行你的代码,因为它会使它看起来像这样:
int MinThree(int x, int y, int z) { return x <= y && x <= z ? x : y <= z ? y : z; }
:(
我是,我也是.也就是说,我在家里使用Lisp,在工作中使用C#,在C#中我确实想念Lisp.这个问题有点滑稽,因为我不认为(Common)Lisp比C#或Ruby或任何其他多范式语言更具"功能性".
一般来说,C#的功能正在逐渐变得相当不错,他们可能已经足够好了,如果有点尴尬的话.(Common Lisp对函数式编程的支持肯定也不完美!)但Common Lisp是一种多范式语言; C#没有(也可能永远)不会在语法抽象,代码生成,方法调度灵活性等方面匹配Lisp.
如果你正在寻找避免学习Lisp的借口,因为你认为C#同样强大,抱歉.:-)