我有一本关于F#的书,但此刻我很不知情,所以我想我会问。 从很少有人知道F#,我很难看到它在C#bar上获得了什么可能的语法整洁。在概念上似乎没什么新东西,或者说在piian C#中不可行。
我做了Forth回来的时候(20年前差不多!)而且我已经将传递函数委托作为参数合并到方法中(似乎永远做了那种事情,似乎)。
从文体上来说,我并不热衷于匿名方法 - 这会成为一个问题吗?
虽然我认为句法整洁不应该被嗤之以鼻: - )
答案 0 :(得分:13)
(警告:第一点不是你问题的答案。作为F#团队的成员,我非常偏颇。)我已经使用F#近一年了,我发现每当我需要写C#代码感觉就像走过泥巴。有这么多的cur and和分号,哦,我的天哪,让我自己写的所有类型!它感觉慢。我使用了大量的C#代码,所以我几乎每天都在阅读和调试它,这对于它来说很好(甚至比F#更好用于调试;我们仍然需要稍微改进F#调试器集成),但我发现< em>写 C#代码现在感觉像是一件苦差事; F#对代码来说更加愉快。
至于你问题的实际答案,很多人都会说'元组',但我会说'嗯'。类型推断,区分联合和模式匹配,功能库,流水线和语法整洁(语法问题!)对我来说是更大的赢家。 (如果你今天要编写异步代码,F#就会把其他人打开。)
答案 1 :(得分:11)
我喜欢F#和C#,但一般我更喜欢F#:
我想说如果你尝试在C#中使用不可变编程,很快就会遇到一个问题,即你不能从方法/函数返回多个东西。 F#使用元组巧妙地解决,以允许您返回多个值。
C#中代表的另一个问题是它们是名义上的。您可以让两个代表具有完全相同的签名,但它们不兼容只是因为它们具有不同的名称。您可以使用lambdas或匿名委托解决此问题,但F#以更清晰的方式解决:它只是检查签名是否匹配。
联盟类型很棒,很难看到C#提供这种功能。
答案 2 :(得分:6)
除了其他答案:自动泛化。
这使得F#在C#,Scala等方面迈出了巨大的一步。这里有一个简单的例子,“snd”函数可以从一对中获取第二个值。在F#中:
let snd (a,b) = b
编译器自动计算出来并使其完全通用:
val snd : 'a * 'b -> 'b
在C#中:
static Tb snd<Ta, Tb>(Tuple<Ta, Tb> x) { return x.B; }
代码的1/3,噪音减少100%。现在,将它扩展到更复杂的函数类型,比如,取一个元组的东西,并将一些枚举的字典返回给函数。哎哟。
这些都是简单的场景。添加一些通用约束,类型参数之间的关系,以及它在C#中变得非常困难。使用C#几次,我必须真正停下来,思考并计算我需要哪些通用参数,即使它不是一个困难的应用程序。在F#中,我可以编写这个想法,一般来说,事情会尽可能地得到推广,而我没有进一步的工作。可爱。
答案 3 :(得分:5)
另一大优势是完整类型推理系统。本地函数,lambdas,元组和列表非常少地减少了代码。
答案 4 :(得分:4)
我认为F#的一大优势是对元组的更好支持。
答案 5 :(得分:4)
是的,在这个时刻,优势是“只是”模式匹配,默认的不变性,更简单(但不太熟悉)的语法,以及非常好的类型推断。
对我来说两个大的(不计算类型推断)是很多更好的monadic语法(F#中的计算表达式与C#中的LINQ查询)和引用(与LINQ表达式相比)。
答案 6 :(得分:3)
我必须说他们处理F#中的Async和并行性的方式令人印象深刻......令人印象深刻。 Check out this video from PDC
答案 7 :(得分:2)
我发现很难以某种简单的方式呈现这些好处。我的信念是,好处不在于某些语言特征(默认情况下是不可动摇的,类型推理或此处提到的任何其他内容)。不同之处在于使用F#时可以使用的完全不同的开发风格。
您可以找到更多信息:
希望这有帮助!
答案 8 :(得分:1)
功能编程与面向对象编程有很大不同。但是,由于F#是一种面向对象的函数式语言,并且由于C#是一种面向对象的功能语言,因此这两种语言看起来非常接近。
答案 9 :(得分:0)
有些像歧视的工会,但我得出了与你完全相同的结论。
而且我不是元组的忠实粉丝 - 我喜欢命名属性,所以我不需要按位置记住所有内容。
像immutabiliy这样的东西是假的 - 因为你可以用C#做到这一点,希望C#5也能让它变得更容易。
重新语法整洁......我觉得C#更整洁,更容易理解,可能很熟悉。
有一个更好的切换语法,但可以将其引入C# - 请参阅here(包括回复)。 Re anon-methods,没有人强迫你使用它们,但lambdas在许多情况下表达意图是一种非常整洁的方式。