abstract V2 : string
type public C1() =
interface I1 with
member this.V1 = "C1"
type public C2() =
inherit C1()
interface I2 with
member this.V2 = "C2"
More flexibility for list literals and subtyping
List and array literals may now be used to create collections from elements that are subtypes of the collection element type. For example:
let myControls: (Control list) = [ new Button() ; new TextBox() ]
F# Compiler
HTML doc generation moved from compiler to PowerPack
The --generatehtml compiler option has been removed, and the functionality moved into a separate tool in the F# PowerPack (see below). This enables decaoupling documentation generation from compilation, and more customization of doc generation.
F# Binary Compatibility 2.0-4.0
As we have discussed with the F# community, full ongoing binary compatibility is expected starting with the version of F# that comes with the Visual Studio 2010 RTM release.
This release has taken crucial steps towards the F# team goal of ensuring binary compatibility for components across .NET 2.0-4.0. For example, in previous releases different copies of the F# Power Pack were required for .NET 2.0-3.5 and 4.0. However, in this release we have one version of the Power Pack which can be used on both .NET 2.0-4.0 (installed via the CTP MSI or ZIP).
If you are authoring F# binary components, you can now build binary compatible components in a similar way. There are some important caveats to this due to two missing type forwarders in FSharp.Core.dll, notably
Ø DLLs using Array2D.* or 2D arrays in public API surface area are not automatically binary compatible across 2.0/4.0. With care these DLLs can be made binary compatible across 2.0/4.0, and this has been done for the F# Power Pack, but normally these APIs will not be binary compatible across 2.0/4.0 until Visual Studio 2010 RTM
Ø Likewise DLLs using F# lazy values (System.Lazy<_>) are not automatically binary compatible. With care, these DLLs can be made binary compatible across 2.0/4.0 by using a private copy of the F# lazy implementation from .NET 2.0, and this has been done for the F# Power Pack. However in the absence of special attention these APIs will not be binary compatible across 2.0/4.0 until Visual Studio 2010 RTM
Binary compatibility can be checked in part by running peverify for .NET 2.0 and .NET 4.0 after installing Visual Studio 2010, a version of Visual Studio 2008 and the F# CTP.
F# Core Libraries
Async API Additions for Web Programming
The extension methods webClient.AsyncDownloadString and webRequest.AsyncGetResponse are now defined in FSharp.Core.dll, and accessed via
open Microsoft.FSharp.Control.WebExtensions
For example:
open System.Windows.Forms
open System.Net
open System.IO
open Microsoft.FSharp.Control.WebExtensions
/// Fetch the contents of a web page, asynchronously
let httpAsync (url:string) =
async { let req = WebRequest.Create(url)
let! resp = req.AsyncGetResponse()
// the rest is a callback
use stream = resp.GetResponseStream()
use reader = new StreamReader(stream)
return reader.ReadToEnd() }
Async API Additions for WinForms, WPF, Silverlight and ASP.NET applications
The Async API has a number of new additions and design extensions to better enable writing “single-primary-thread-of-control” reactive applications using F# asyncs. This is a commonly used idiom for Windows Forms, WPF, Silverlight and ASP.NET programming.
These applications are I/O parallel, but only use CPU parallelism in constrained ways. In this kind of application, CPU processing is done on a single thread of control, but multiple I/O requests may be overlapped.
In .NET, these applications will typically have a non-null, dedicated value for System.Threading.SynchronizationContext.Current on the main “thread”.
Waiting for .NET Events
The method Async.AwaitEvent is now defined in FSharp.Core.dll. This method runs the continuation of the async the first time .NET event fires.
open System.Windows.Forms
let form = new Form(Visible=true,TopMost=true)
async { let! firstClick = Async.AwaitEvent form.Click
form.Text <- "I got clicked once!"
let! nextClick = Async.AwaitEvent form.Click
form.Text <- "I got clicked twice!" }
|> Async.StartImmediate
Starting Asyncs on the Current Thread
The methods Async.StartImmediate and Async.StartWithContinuations are now defined in FSharp.Core.dll. These methods start the async immediately on the current thread, until the first point where the thread yields through an operation such as Async.AwaitEvent or an I/O operation.
These methods are particularly useful for starting async operations on the GUI or ASP.NET thread.
A use of StartImmediate is shown above.
Automatic Return to Context
F# library async I/O and waiting primitives can now be used from GUI or ASP.NET threads in a simpler fashion. Conceptually, if you start an async I/O operation or an async wait operation on a GUI thread, then it will “complete” on the GUI or ASP.NET thread.
If a primitive async operation is started on a thread where SynchronizationContext.Current is set, then the continuation of such an async is posted using SynchronizationContext.Post.
In the following example the overall async is started on the GUI thread using StartImmediate. As the click happens and the asynchronous fetches of the web pages return, the overall async is in each instance continued on the GUI thread. This means the GUI components can be safely updated from the async.
open System.Windows.Forms
let form = new Form(Visible=true,TopMost=true)
async { let! firstClick = Async.AwaitEvent form.Click
form.Text <- "I got clicked!"
let! firstPage = httpAsync "http://www.google.com"
form.Text <- "I got the first page!"
let! secondPage = httpAsync "http://www.bing.com"
form.Text <- "I got the second page!" }
|> Async.StartImmediate
F# asyncs built using the following API operations implement “automatic return to context”:
Async.Parallel
Async.Sleep
Async.AwaitEvent
Async.AwaitIAsyncResult
Async.AwaitTask
Async.AwaitWaitHandle
Async.FromBeginEnd
Async.FromContinuations
type System.Net.WebRequest with
member AsyncGetResponse()
type System.Net.WebClient with
member AsyncDownloadString()
type System.IO.Stream with
member AsyncRead()
member AsyncWrite()
Async API Renamings
System.Threading.AsyncSleep -> Async.Sleep
extension waitHandle.AsyncWaitOne -> Async.AwaitWaitHandle
extension waitHandle.AsyncWaitOne -> Async.AwaitWaitHandle
Async.BuildPrimitive -> Async.FromBeginEnd
Async.SwitchToGuiThread -> Async.SwitchToContext
Async.RunWithContinuations -> Async.StartWithContinuations
Complete the under_score -> camelCase name standardization, of_list -> ofList
The naming normalization across the F# core libraries is finalized in this release, with the following removals of underscores and abbreviations:
to_list -> toList
to_array -> toArray
to_seq -> toSeq
of_list -> ofList
of_array -> ofArray
of_seq -> ofSeq
of_nativeint -> ofNativeInt
to_nativeint -> toNativeInt
hd -> head
tl -> tail
Observable module and F# events
The IObservable and IObserver interfaces provide a general interface over observable data, which can be easily composed. These interfaces are provided in .NET4.0, and are available in F# for .NET2.0.
1st class events in F# now implement the IObservable interface, enabling them to interoperate with other IObservable programming models. A new Observable module in the F# library provides compositional functions for manipulating general Observable data:
Observable.merge
Observable.map
Observable.filter
Observable.partition
Observable.split
Observable.choose
Observable.scan
Observable.add
Observable.subscribe
Observable.pairwise
array2D enables easily creating 2D arrays
A new ‘array2D’ function converts data into 2d arrays:
let matrix = array2D [[1;2;3];
[2;3;4];
[3;4;5]]
[.NET 4.0] Lazy, CancellationToken, BigInteger in .NET4.0
Some F# types have moved into mscorlib in .NET4.0, making it easier to reuse these types between F# and other .NET languages. On .NET2.0, these F# types have been moved to corresponding namespaces within FSharp.Core.dll. The following important F# types have moved to System namespaces:
Lazy -> System.Lazy
Tuple -> System.Tuple
BigInt -> System.Numerics.BigInteger
AsyncGroup -> System.Threading.CancellationTokenSource and System.Threading.CancellationToken
CompiledName used to ensure .NET view is C#/VB friendly
The .NET-visible names of types and members in FSharp.Core.dll are modified to align with standard .NET naming conventions. This makes it easier to use FSharp.Core defined types from other .NET languages. For example:
Seq.iteri -> Microsoft.FSharp.Collections.SeqModule.IterateIndexed
failwith -> Microsoft.FSharp.Core.Operators.FailWith
Visual Studio
[VS2010] Multitargeting support for 2.0-4.0 + Silverlight
With VS2010, F# users can target .NET 2.0, 3.0, 3.5, 3.5 Client, 4.0 and 4.0 Client. F# libraries can also be built targeting Silverlight 2 and 3. F# libraries built against .NET2.0 can also be used as part of F# applications targeting later versions of .NET.
Error list improvements
The Visual Studio error list is populated with F# errors both during editing of F# files, and during building of F# projects. This release ensures that errors are tracked between these two sources when they are available in both.
F1 support
F1 contextual help support is available in the F# editor. This will open documentation for the type or member reference at the cursor. In addition, in VS2010, F1 help on F# keywords or F# library functions will go to the new MSDN documentation on these subjects.
F# Interactive
#load .fsx
When building complex F# scripts, it is sometimes necessary to split a script into multiple .fsx files. F# scripts now support the ability to load other F# scripts, enabling factoring of scripts into source components.
F# PowerPack
FsHtmlDoc.exe
A new tool called fshtmldoc.exe is now available in the F# Power Pack. This replaces the HTML doc functionality in the F# compiler. The command line options are shown using “fshtmldoc.exe --help"