在过去的几年中,f#已经发展成为微软完全支持的语言之一,使用了OCaml、ML和Haskell中孵化的许多思想。

在过去的几年里,c#通过引入越来越多的函数式语言特性扩展了它的通用特性:LINQ(列表理解)、Lambdas、闭包、匿名委托等等……

考虑到c#采用了这些函数特性,以及f#作为一种非纯函数语言的分类(它允许你访问框架库,或者当你想要调用函数时改变共享状态),这两种语言之间有很强的相似性,尽管每种语言都有自己截然相反的主要重点。

我感兴趣的是在你的多语言生产程序中使用这两种语言的任何成功模型,以及在生产软件(web应用程序,客户端应用程序,服务器应用程序)中,你在过去一年左右的时间里用f#写的东西,而你以前用c#写的东西。


当前回答

在过去的6个月左右的时间里,我一直在为Visual Studio 2010开发Vim模拟层。这是一个免费的产品,所有的源代码都可以在github上免费获得

GitHub: http://github.com/jaredpar/VsVim VsVim在Visual Studio画廊

该项目分为3个DLL,代表一个不同的层。每一层都有一个相应的单元测试dll。

Vim引擎:f# 用于装饰和编辑器集成的WPF层:c# Visual Studio集成层:c#

这是我用f#做的第一个大项目,我不得不说我喜欢这门语言。在很多方面,我把这个项目作为学习f#的一种方法(如果你看看这个项目的历史,你会发现这个学习曲线非常明显)。

我发现f#最令人惊奇的是它是一种多么简洁的语言。Vim引擎包含了大部分的逻辑,但它只包含了整个代码库的30%。

其他回答

不是个人经验,但你可以听一集DNR(我想是这个),他们和微软的人谈论f#。他们使用f#编写了大部分Xbox Live评分系统,这远非微不足道。该系统在数百台机器上大规模扩展,他们对此非常满意。

我目前正在为一种编程语言编译。编译器完全是用f#编写的。编译器(除了用lex/yacc构建的lex和解析器)基本上是构建为一个复杂的树状结构的大量转换。

正如其他人所指出的那样,区别并集和模式匹配使得处理这种数据结构比将代码“到处”转储到虚拟方法中要容易得多。

在我开始编写编译器之前,我没有做过任何f#工作(然而,我在另一个OCaml变体中构建了编译器,称为MoscowML),正如Jared所说,从代码中可以看出我首先做了哪些部分,但总的来说,我发现f#很容易学习,在主要面向对象编码十年之后,再次进入FP思维模式,尽管需要更长一点的时间。

除了使用树,我发现编写声明性代码的能力是FP(包括f#)的主要好处,与c#描述我如何实现算法相比,有代码描述我试图实现的算法是一个巨大的优势。

在微软研究院实习期间,我参与了Visual Studio IntelliSense for f#的部分工作(它本身就是用f#编写的)。我在早期的c#项目中已经有了一些智能感知的经验,所以我认为我可以比较这两者。

Visual Studio Extensibility is still based on COM, so you need to deal with objects that are not very nice .NET objects (and definitely not functional), but I don't feel there is any major difference between C# and F# (it works smoothly from F#) The data structures used to represent program code in F# are mostly discriminated unions (which are not supported in C# in any reasonable way) and this makes a huge difference for this kind of application (where you need to process tree structures, such as program code). Discriminated unions and pattern matching allows you to structure the code better (keep related functionality in one place rather than having it all over the place in virtual methods)

之前,我还为f#开发了CodeDOM提供程序(也是用f#编写的)。实际上,我首先用c#做了实验,但随后将代码转换为f#。

CodeDOM provider needs to traverse some structure represented using .NET objects, so there isn't much space for inventing your own representations of data (which is the area where F# can offer nice benefits). However, there were many small F# features that made the task easier. Since you need to produce a string, I defined custom operators for building strings (using StringBuilder) and implemented the code using them and higher-order functions (e.g. to format list of objects separated using the specified string etc.), which removed a lot of repetition (and tedious foreach loops).

这是两个相对具体的示例,但它们都与处理程序或表达式的表示有关,或者更一般地说,与复杂的树状数据结构有关。我认为在这方面,f#绝对是一个很好的选择(不管c#中的函数特性)。

f# Visual Studio组件的很多单元测试都是用f#编写的。它们在VS外部运行,模仿Visual Studio的各种功能。将实现接口的匿名对象组合起来的能力可以代替模拟框架/工具。我可以这样写

let owpe : string list ref = ref []
let vsOutputWindowPane = 
    { new IVsOutputWindowPane with
        member this.Activate () = err(__LINE__)
        member this.Clear () = owpe := []; 0
        member this.FlushToTaskList () = VSConstants.S_OK
        member this.GetName(pbstrPaneName) = err(__LINE__)
        member this.Hide () = err(__LINE__)
        member this.OutputString(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputStringThreadSafe(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputTaskItemString(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText) = err(__LINE__)
        member this.OutputTaskItemStringEx(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText, pszLookupKwd) = err(__LINE__)
        member this.SetName(pszPaneName) = err(__LINE__)
    }            
DoSomethingThatNeedsA(vsOutputWindowPane)
assert( !owpe = expectedOutputStringList )

当我需要一个实例,例如,一个IVsOutputWindowPane传递给一些其他组件,最终将调用OutputString和清除,然后检查字符串列表ref对象在测试结束,看看预期的输出是否被写入。

我们发布了世界上第一个用f#编写的商业产品(f# for Visualization)和第二个(f# for Numerics),以及第一个关于f#的商业文献(the f#。NET Journal),并撰写并出版了关于f#当前版本的唯一一本书(Visual f# 2010 for Technical Computing)。

We had been shipping products along similar lines written in C# (e.g. this) but we also had a strong background in the commercial use of OCaml. We were enthusiastic early adopters of F# when it was still a research prototype back in 2006 because we recognised the potential of having a decent modern OCaml-like language on the industrial-strength .NET platform and, consequently, we pushed to have it productized. The result has been an incredible success and F# has far exceeded our lofty expectations.

For us, F# has many different advantages and we use it for a wide variety of applications. We have hundreds of thousands of lines of F# code in production. We now use F# for all of our LOB apps: our credit card transactions are processed using F# code, our product notifications are sent using F# code, our subscriptions are handled using F# code, our accounts are done using F# code and so on. Perhaps the main language feature that pays dividends here is pattern matching. We even used F# to color syntax highlight our latest book...

Our visualization library is a big seller and its functionality centers on F# interactive running in Visual Studio. Our library augments this with the ability to spawn interactive 2D and 3D visualizations with minimal effort (e.g. just Plot([Function sin], (-6., 6.)) to plot a sine wave). In particular, all threading issues are completely automated so users do not have to worry about UI threads and dispatch. First-class functions and laziness were extremely valuable when writing this part of the library and algebraic datatypes were used extensively elsewhere. Predictable performance also proved to be valuable here when our customers hit performance bugs in WPF's hit testing and were easily able to reimplement the relevant code in F# for a 10,000× performance improvement. Due to the free-form nature of this product's GUI, the GUI designer and C# would not have been beneficial.

Much of our work revolves around numerical methods, including both our commercial libraries and books. F# is much stronger in this area than C# because it offers high-level abstractions (e.g. higher-order functions) with minimal performance penalties. Our most compelling result in this context was the creation of a simple but generalized implementation of QR decomposition from linear algebra that was 20× shorter than the Fortran code from the reference implementation of LAPACK, up to 3× faster than the vendor-tuned Intel Math Kernel Library and more generic because our code can handle matrices of any type, even symbolic matrices!

目前,我们正在开发WPF/Silverlight组件,混合使用f#(用于guts)和c#(用于shim),构建WPF应用程序作为我们软件产品的交互手册,我正在写一本新书,多核f#,它将是。net上共享内存并行编程的权威指南。