F# 对于 OO 或命令式来说缺少什么?
我多次听说 F# 不适合特定任务,例如 UI。 “使用正确的工具”是一个常见的短语。
除了缺少 WinForms/WPF/ORM 设计器等工具之外,我不确定 F# 中到底缺少什么——老实说! 然而,特别是在 UI 方面,我听说 C# 做得更好。 那么,F# 在命令式使用时实际的差异和遗漏是什么?
以下是我列出的列表:
许多缺少的工具支持
F# 仍然是测试版
您的开发人员不知道F#
- 我不想考虑这些要点,因为它们并不是 F# 真正固有的
可变对象需要“可变”或需要引用,引用需要! 取消引用
Mutables 使用 <- 进行赋值,并且 ref 使用 := (它们都比 = 多 1 个字符)
val 需要 DefaultValueAttribute 来获取默认值
F# 不会发出隐式接口
- < p>受保护的成员更难处理
没有自动属性
抽象类上实现的虚拟成员需要两个定义
Quotations-to-LINQ-Expression-Trees 生成的树与 C#/VB 略有不同(对于期望其表达式采用特定格式的 API 来说很烦人)
无 stackalloc
F# 没有 ?: 条件运算符
F# 中的指针可能被认为更麻烦
委托/事件可能被认为更麻烦(我认为它们更容易,但至少它们是不同的)
没有自动类型转换(如 int 到 float 或隐式转换)
没有对 Nullable 的特殊语法支持(C# 的 ? 类型注释和 ?? 运算符,以及在可空值上使用运算符。)
没有自动向上转换为公共基类或装箱(例如:let x : obj = if true then 1 else "hi" // 这不会进行类型检查)
在没有警告的情况下不能丢弃值(“ignore”来绕过它)
没有 C 风格的语法 :)
对于这个问题:以下哪一个是编写命令式或 OO 代码的障碍? 为什么(简短的例子)? 我错过了哪些? 最好的解决方法是什么?为什么它们还不够?
请注意,我不是在谈论编写所谓的惯用 F#,当然也不是在谈论函数式编程。 我更感兴趣的是“如果我强迫自己在 F# 中编写 UI 或命令式/OO 代码,使用 F# OO/命令式功能和类类型,什么伤害最大?”
奖金 如果您不了解 F#,但使用 C# 或 VB.NET,并且认为它在某些情况下是更好的工具,请指出您认为有吸引力的特定语言功能和语法。
Many times I hear that F# is not suited to particular tasks, such as UI. "Use the right tool" is a common phrase.
Apart from missing tools such as a WinForms/WPF/ORM designer, I'm not sure what exactly is missing in F# -- honestly! Yet, particularly with UI, I'm told that C# just does it better. So, what are the actual differences and omissions in F# when using it imperatively?
Here is a list I came up with:
Lots of missing tool support
F# is still beta
Your developers don't know F#
- I'd like to not consider those points, as they aren't really intrinsic to F#
Mutables need "mutable" or need to be ref, ref needs ! to dereference
Mutables assign with <- and ref uses := ( they're both 1 more character than just = )
val needs DefaultValueAttribute to get a default value
F# doesn't emit implicit interfaces
Protected members are more difficult to deal with
No automatic properties
Implemented virtual members on abstract classes require two definitions
Quotations-to-LINQ-Expression-Trees produces trees slightly different than C#/VB (annoying for APIs that expect their Expressions in a specific format)
No stackalloc
F# doesn't have the ?: conditional operator
Pointers might be considered more cumbersome in F#
Delegates/events might possibly be considered more cumbersome (I'd argue they're easier, but at a minimum they're different)
No automatic type conversions (like int to float, or implicit casts)
No special syntax support for Nullable (C#'s ? type annotation and ?? operator, as well as using operators on nullables.)
No automatic upcasting to common base class or boxing (ex: let x : obj = if true then 1 else "hi" // this won't typecheck)
Values can't be discarded without a warning ("ignore" to get around it)
Doesn't have C-style syntax :)
To the question: Which of these are a hindrance to writing imperative or OO code? Why (short examples)? Which ones did I miss? What are the best workarounds, and why are they not enough?
Please note, I'm not talking about writing so-called idiomatic F#, and I'm certainly not talking about functional programming. I'm more interested along the lines of "If I were to force myself to write UI or imperative/OO code in F#, using F# OO/imperative features and class types, what hurts the most?"
Bonus
If you don't know F# but use C# or VB.NET and think it's a better tool for some situations, please indicate the specific language features and syntax you find appealing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我不太喜欢这个问题,因为它抱怨 F# 不支持惯用的 C#。 例如,我认为批评 F# 使用 <- 和 := 进行变量赋值是不公平的,因为该语言默认使事物不可变。
无论如何,有一些命令式/面向对象的事情可以在 C# 中完成,而在 F# 中却无法完成。
F# 不支持嵌套类。 在 C# 中,您可以在另一个类的主体中声明一个类,作为确定类型范围的机制。 F# 不支持这一点。
F# 不允许您两次实现相同的通用接口。 例如,在 C# 中,您可以在同一类型上实现
IComparable
和IComparable
。在 F# 中,您必须具有架构分层。 由于 F# 的类型推断,您只能使用已在类型声明“之前”或同一类型声明“块”中声明的类。 然而,在 C# 中,您可以引用任何其他类。 (这实际上强制执行了一些良好的编程实践。)
F# 没有对 LINQ 的“本机”支持,如没有 from 关键字。 不过,您可以使用 LINQ API 和 lambda 表达式来获得相同的结果。
F# 可以做而 C# 不能做的事情:
受歧视的联合。 这使得在 F# 中创建树状数据结构变得很简单,而在 C# 中您必须求助于复杂的类型层次结构。
异步工作流程。 F# 库的这一功能消除了与 APM 相关的所有麻烦,从而使异步和并行编程变得更加简单。
模式匹配和活动模式。
用于消除与使用错误单位相关的错误的度量单位。 (例如,在“米”中添加“英尺”。)
等等
您不应该关注 F#“不能像 C# 那样做”的事情,因为学习 F# 的全部目的是提出了一种解决问题的新方法。 如果您在 F# 中编写惯用的 C# 代码,您实际上并没有获得任何好处。
AFAIK F# 并没有缺少 .NET / COM 互操作的任何“必备功能”。 在 F# 中,您可以执行诸如使用 out 和 byref 参数、声明字符串文字以及支持在任何内容上添加属性等操作。
I'm not a huge fan of this question as it complains about F# not supporting idiomatic C#. For example, I don't think it's fair to criticize F# for using <- and := for variable assignment because the language makes things immutable by default.
Regardless, there are several imperative / object-oriented things you can do in C# that you simply cannot in F#.
F# doesn't not support nested classes. In C# you can declare a class within the body of another class as a mechanism for scoping types. F# does not support this.
F# doesn't allow you to implement the same generic interface twice. For example, in C# you can implement
IComparable<int>
andIComparable<string>
on the same type.In F# you must have architectural layering. Due to F#'s type inference you can only use classes that have been declared 'before' or in the same 'block' of type declarations. In C# however you can have any class reference any other. (This actually enforces some good programming practices.)
F# doesn't have 'native' support for LINQ, as in no from keyword. However, you can use LINQ APIs and lambda expressions to achieve the same result.
Things that F# can do that C# can't:
Discriminated unions. This makes it trivial to create tree-like data structures in F#, where in C# you'd have to resort to a complex type hierarchy.
Asynchronous workflows. This feature of the F# library makes asynchronous and parallel programming much more paletable by abstracting away all the pain associated with the APM.
Pattern matching and active patterns.
Units of measure for eliminating bugs associated with using the wrong units. (E.g., adding 'feet' to 'meters'.)
etc.
You shouldn't focus on what F# 'can't do like C#' because the whole point of learning F# is to be presented with a new way to think about problem solving. If you write idiomatic C# code in F# you aren't actually gaining anything.
AFAIK F# isn't missing any 'must haves' for .NET / COM interop. In F# you can do things like have out and byref parameters, declare string literals, and support putting attributes on just just about anything.
F# 中的命令式编程比人们想象的要好得多。 F# 的 匹配语句 是惊人的。 为什么其他语言没有实现我不知道。 至于语法(可变、引用等)之类的东西,它们很容易使用。 您会被 F# 的稀疏性宠坏,并且当语法比正常情况大时很容易抱怨。 元组也很棒。 它们也将采用 C# 4.0。 柯里化是命令式的另一个好处。
关于 OO,我发现我很少在纯 F# 项目中使用继承,而是更喜欢组合和接口。 这主要是由于使用了主要构造函数 允许您在方法中使用它的参数作为私有属性(不确定我的措辞是否正确)。 其他语言结构(例如模式匹配)也会让您远离继承。 我没有做过任何 C#/F# 混合项目,所以我无法对此发表评论。
F# 并不都是玫瑰。
我对 F# 和游戏编程最大的问题是性能。 在 F# 中实现速度非常快,我经常在想到它的同一天就得到一个原型并运行我想做的事情,但我发现自己出于性能原因重写代码比在 C# 中更频繁。
部分问题是我对函数式编程风格缺乏经验,函数式编程风格是使用 Seq、List、Map 及其所有附带方法,如 map、iter、fold、scan。 我的第一个功能解决方案几乎从来都不是最快的,而我的第一个程序解决方案几乎总是接近最佳解决方案。 我想说这不是我的一部分。 在某些情况下,函数式编程并不能提高性能。
我现在在 F# 中使用的函数数据类型比刚开始时要少。
编辑:
自从我发布此内容以来已经过去了很多个月,我不再遇到性能问题。 我的第一个功能解决方案通常更简单,现在几乎是最佳的,并且不可变的数据结构也很简单。 我现在遇到的唯一性能问题是 CLI,如果需要的话我总是可以执行 c++/cli。 除了接口之外,我现在确实使用了一些继承,但它仅适用于匿名对象。
Imperative programming in F# is much better than people would lead you to believe. F#'s match statement is awesome. Why other languages have not implemented it I don't know. As far as things like syntax (mutable, ref, etc) they are easy to work with. You get spoiled by F#'s sparseness and it's easy to complain when the syntax is bigger than normal. Tuples are also great. They will be in C# 4.0 too. Currying is another bonus for Imperative.
Concerning OO I find I rarely use inheritance in pure F# projects and favor composition and interfaces instead. This is mainly due to using the primary contructor that allows you to use it's parameters as private properties in your methods (not sure if I worded that correctly). Other language constructs such as pattern matching pull you away from inheritance too. I've not done any mixed projects C#/F# so I can't comment on that.
F# isn't all roses.
My biggest issue with F# and game programming is performance. Implementing in F# is really fast and I often get a prototype up and running for what I want to do the same day I think of it however I find myself rewriting code for performance reasons way more often than in C#.
Part of the problem is my inexperience with functional programming style that is to use Seq, List, Map and all their accompanying methods such as map, iter, fold, scan. My first functional solution is almost never the fastest while my first procedural solution is almost always close to the best possible. I want to say part of this isn't me. That functional programming doesn't lend its self to performance in some situations.
I use less of the functional data types in F# now than when I started.
EDIT:
Many months have gone by since I've posted this and I no longer have issues with performance. My first functional solutions are often simpler and nearly optimal now and immutable data structures are simple. The only performance issues I have now are with the CLI and I can always do c++/cli if I need to. I do use some inheritance besides interfaces now but it's only for anonymous objects.
关于面向对象的东西,我的清单可能是:
也就是说,F# 在 OO 领域也有优势,比如类型推断、本地函数、简洁语法……所以总的来说,我可能会称其为“重度 OO 领域的洗礼” ' 部门。
(我几乎没有做过任何类型的 UI 编程,所以没有资格在那里权衡。)
(编辑:我也想插一句,即使你明确选择从问题中排除“工具”,我认为工具很重要,在这方面,其他托管 VS 语言表现出色。)
With regards to OO stuff, my list might be
That said, F# has strengths in the OO department too, like type inference, local functions, succinct syntax, ... so overall I might call it a wash in the 'heavily OO' department.
(I have done almost no UI programming of any kind, so am not qualified to weigh in there.)
(EDIT: I also want to interject that, even though you're explicitly choosing to exclude 'tooling' from the question, I think tooling matters a bit, and in this respect the other managed VS languages excel.)
我对静态类型函数语言最大的痛苦是无法在需要推断的方法上使用可变参数。 就像地图功能一样。 在 F# 中,您需要 map2、map3 等。
另一方面,C# 也缺少这个,除非您想通过反射。
以Scheme为例,它不是静态类型的。 定义一个可以处理 map_1 ... map_n 的所有情况的函数并不存在问题。 当然,您失去了静态类型安全性,但与编写简洁代码的额外便利相比,它显得相形见绌。
My biggest pain with statically typed functional languages is inability to have variable arguments on a method that needs to be inferred. Like the map function. In F# you need map2 map3, etc.
On the other hand C# lacks this too, unless you want to go via reflection.
Take Scheme for example, that is not statically typed. You do not have an issue to define a single function that can handle all the cases of map_1 ... map_n. Sure you loose static type safeness, but it pales in comparison to the additional convenience of writing concise code.
仅供记录:F# 具有堆栈分配 - 尝试非尾递归的无限递归,您将遇到堆栈溢出。 这与 C# 中的堆栈分配实际上没有什么不同,除了您知道可以安全地使用 F# 尾递归(在 C# 中视情况而定)。
另外,我想指出的是,当您使用非常繁重的面向事件的代码时,F# 的扩展性比 C# 更好,因为它允许您构建一个框架来执行将事件分派给处理程序等的“管道”工作,而无需将管道变成你的大部分代码。 对于简单的 UI,C# 或 VB 可能适合更多人。 对于复杂的情况,F# 会领先,而且我个人在复杂的情况下比简单的情况更需要帮助。
Just for the record: F# has stack allocation - try an infinite recursion that's not tail recursive and you'll get a stack overflow. It's really no different to stack allocation in C#, aside from you knowing that you can use tail recursion safely F# (in C# it depends).
Also, I'd point out that when you get to really heavy event oriented code, F# scales better than C# in terms of allowing you to build up a framework to do the "plumbing" of dispatching events to handlers, etc without the plumbing becoming the majority of your code. For a simple UI, C# or VB may suit more people. For complicated situations, F# pulls ahead, and personally I need help with the complicated situations more than the simple ones.