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

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

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

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


当前回答

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

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

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

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

其他回答

我们使用f#中的Lex-Yacc实现编写了一个自定义规则引擎语言

编辑以包括评论回复

c#中没有lex/yacc实现。(据我们所知,f#是)

这本来是可能的,但我们自己构建解析是非常痛苦的。

这个主题展示了一些其他的建议,比如外部库,但是我们的首席架构师是函数语言的老手,所以选择使用f#是很容易的。

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

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

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

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

我们发布了世界上第一个用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上共享内存并行编程的权威指南。

我不知道《the Path of Go》的AI是否正在制作中,但它是用f#编写的:

http://research.microsoft.com/en-us/events/techvista2010/demolist.aspx#ThePathofGo

The Path of Go: A Microsoft Research Game for Xbox 360 This demo showcases an Xbox 360 game, based on the game of Go, produced in-house at Microsoft Research Cambridge. Go is one of the most famous board games in East Asia, it originated in China 4000 years ago. Behind the deceptive simplicity of the game hides great complexity. It only takes minutes to learn, but it takes a lifetime to master. Although computers have surpassed human skills at Chess, implementing a competitive AI for Go remains a research challenge. The game is powered by three technologies developed at Microsoft Research Cambridge: an AI capable of playing Go, the F# language, and TrueSkill™ to match online players. The AI is implemented in F# and meets the challenge of running efficiently in the .net compact framework on Xbox 360. This game places you in a number of visually stunning 3D scenes. It was fully developed in managed code using the XNA environment.

(已经有人提到了“TrueSkill”。)

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对象在测试结束,看看预期的输出是否被写入。