We are pleased to announce the availability of a preview release of version 3.1 of the F# language, with matching Visual F# tooling. These are included with the Visual Studio 2013 Preview Release announced at //BUILD/ and on Soma’s blog.
F# as a language is both open source and available for cross-platform use through the work of the F# Software Foundation and other contributors. Language design and compiler implementation are two of Microsoft’s contributions to the language, as well as the Visual F# tooling and the Try F# site. As they are finalized, we will be working with the F# community to make the F# 3.1 updates available as an open source release update.
F# 3.1 Language Additions
F# is a stable and mature language, suitable adoption in professional enterprise contexts. Previous versions of the F# language have focused on major new features such as F# asynchronous programming (F# 1.1), F# units of measure (F# 2.0) and F# type providers (F# 3.0). The focus of this version of the F# language is to make incremental improvements to improve the software engineering qualities of the language and make it simpler to use in common situations.
Named union type fields
Discriminated union types are a powerful feature of F# which make programming with shaped data simple, accurate and robust. They also greatly reduce the number of classes needed to represent data in many common circumstances.
In F# 3.1, it is now possible to name union fields within each case of a union type. This is important for large-scale software engineering, particularly when union cases have a large number of fields or multiple fields with the same type.
Extensions to array slicing
F# supports slicing syntax for arrays and other multi-dimensional data structures. However, in previous versions of the language, slicing was restricted to slicing a shape of the same “dimension”, for example, slicing a 2D sub-matrix from a 2D matrix. In this release, you can now slice 1D columns and 1D rows from 2D matrices, and likewise for other slicing operations.
For example, if a matrix type has the appropriate overloads of the GetSlice method, in F# 3.0 it was already possible to do the following:
matrix.[1..,*] -- get rows 1.. from a matrix (returning a matrix)
matrix.[1..3,*] -- get rows 1..3 from a matrix (returning a matrix)
matrix.[*,1..3] -- get columns 1..3from a matrix (returning a matrix)
matrix.[1..3,1,.3] -- get a 3x3 sub-matrix (returning a matrix)
In F# 3.1, you can now also use individual indexes to slice columns and rows:
matrix.[3,*] -- get row 3 from a matrix as a vector
matrix.[*,3] -- get column 3 from a matrix as a vector
The GetSlice overloads needed to enable the above are as follows:
// get a sub-matrix matrix.member x.GetSlice(rowStart: int option, rowFinish: int option, colStart: int option, colFinish: int option) // get a row-vector matrix.member x.GetSlice(row: int, colStart: int option, colFinish: int option) // get a column-vector matrix.member x.GetSlice(rowStart: int option, rowFinish: int option, col: int)
Type inference enhancements for LINQ-style methods
F# 3.1 introduces an additional type inference rule to improve F# type inference when using overloaded methods which take functions as arguments. Improvements are most noticeable when using the LINQ method overloads, addressing the problem described here: http://blogs.msdn.com/b/dsyme/archive/2012/12/07/quicklinq-helpers.aspx, extract below:
Sometimes in F# it is useful to use LINQ extension methods such as .Take(n), .Skip(n) and .Count(). However, in F# some LINQ extension methods such as .Where(...) and .Select(...) require a type annotation on the lambda variable. This is one of the relatively rare cases where F# code requires a type annotation where other languages do not, and is due to differences in the process of type inference and method overload resolution.
… This becomes particularly important when working with provided data sources, where giving type annotations can be problematic. For example when using the Freebase type provider, the type names can be quite long, so
elements.Select(fun (x:FreebaseData.ServiceTypes.Chemistry.Chemistry.Chemical_elementData) ->x.Name )
The rule is an adjustment to F# 3.0 type inference where each argument position for the method call is analyzed to propagate type information extracted from method overloads.
For example, in F# 3.1 you can now simply write:
elements.Select(fun x ->x.Name)
The same annotation-removal applies to most other overloaded fluent-style extension members taking lambda arguments. In some cases, a type annotation may still be necessary.
Support for C# extension members with first parameter a type parameter
Prior to F# 3.1, the F# compiler ignores imported C#-style extension methods with a generic type variable, array type, tuple type or an F# function type as the “this” parameter. F# 3.1 now supports the use of these extension members.
For example, extension methods with signatures like this can now be used in F# code:
static member M(this T input, T other)
This is particularly useful when the generic type parameter is constrained. Further, extension members like this can now also be declared in F# code. This allows additional, semantically rich set of extension methods to be defined in F# code. In F#, extension members are usually defined as follows:
type seq<'T>with /// Repeat each element of the sequence n times member xs.RepeatElements(n:int) = seq { for x in xs do for i in 1 .. n do yield x }
However for a generic type, the type variable may not be constrained. You can now use a C#-style extension member declaration in F# to work around this limitation. When combined with the inline feature of F#, this lets you present generic algorithms as extension members, a uniquely powerful feature of F# amongst .NET languages. For example, the declarations:
[] type ExtraCSharpStyleExtensionMethodsInFSharp () = [] static member inline Sum(xs: seq<'T>) = Seq.sum xs
can be used as follows:
let listOfIntegers = [ 1 .. 100 ] let listOfBigIntegers = [ 1I .. 100I ] listOfIntegers.Sum() listOfBigIntegers.Sum()
Note that we have applied the same generic arithmetic code to lists of two different types, without overloading, and using an extension member.
Ideally, future versions of F# will allow a simpler declaration syntax for these additional extension members. However, in F# 3.1 the focus has been on importing C# extension members, which coincidentally also allowed their declaration in F#, hence providing a route for F# library authors to provide these extension members as part of an API.
Alignment of supported declaration of constants in attributes and literal expressions
In F# 3.1, the specification of constants literal expressions is now better aligned with the specification of constant expressions allowed in attribute arguments.
In particular, literals can now be defined using “+” on strings (very useful for file access involving the __SOURCE_DIRECTORY__ literal), and using combinations of enum flags:
[] let test1 = "a" + "b" [] let test2 = 1 ||| 64 [] let test3 = System.IO.FileAccess.Read ||| System.IO.FileAccess.Write
F# 3.1 Compiler/Library Additions
Printf performance
The F# 3.1 core library sees improved performance of the printf family of functions for type-safe formatting. For example, printing using the following format string now runs up to 40x faster (though your exact mileage may vary):
sprintf "%d: %d, %x %X %d %d %s"
No changes in your code are needed to take advantage of this improved performance, though you do need to be using the F# 3.1 FSharp.Core.dll runtime component.
Debug info in Quotations through --quotations-debug
F# supports a powerful meta-programming feature called Code Quotations. Among other things, this is used as the basis of F# LINQ support and frameworks which compile F# code to JavaScript and to GPGPU code.
In F# 3.1, expressions derived from quotation literals and reflected definitions can now include more debug information. Previously, quotations only carry debug information at the “outermost” expression tree node.
Extra quotation debugging information is enabled through the --quotations-debug switch to fsc.exe and fsi.exe
--quotations-debug Emit debug information in quotations
The debug information is found in the custom attributes of an F# expression tree node.
Support for .NET 4.5 + Windows Store portable libraries
Recent profiles of .NET used for Windows 8 components and libraries portable between .NET 4.5 and Windows 8 use the System.Runtime assembly as the primary system assembly. These are sometimes called the “.NET Core”-style profiles.
F# now supports the generation and consumption of .NET assemblies built for these profiles. This is also important foundational work to align the F# compiler with more recent .NET profiles.
Most concretely, this means that C# portable assemblies built for “.NET 4.5 + Windows Store” can now be consumed by the F# compiler, and that F# programmers can author portable assemblies for this profile combination.
You can create a “.NET 4.5 + Windows Store” portable library by choosing the “F# Portable Library” template. You can create a portable library for “.NET 4.0, Windows Store, Silverlight 5.0” by using the “F# Portable Library (Legacy)” template. Portable libraries are also usable in other cross-platform execution settings such as iOS and Android programming.
Visual F# Tooling in Visual Studio 2013
Round-tripping with Visual Studio 2012
Visual F# projects authored in Visual Studio 2012 can now be used in Visual Studio 2013 without requiring a project upgrade, and vice-versa (if the project is using the F# 3.0 runtime components). For Visual Studio 2012 projects, a one-time upgrade is required to enable this feature, but that upgrade is backwards compatible and the project will still be usable in both Visual Studio 2012 and 2013.
Project round-tripping was not supported for F# between Visual Studio 2010 and 2012, but it is now supported between Visual Studio 2012 and 2013.
While easy to describe, this is a hugely important feature for teams and collaborative projects using F# in Visual Studio. For example, an open source collaborative project can now more readily have contributors using multiple versions of Visual Studio.
Simple UI for choosing F# runtime and multi-targeting between F# 3.0 and 3.1
The Visual F# project dialog now allows you to choose the F# runtime (FSharp.Core.dll) version you are targeting with your project:
The same capability is present directly from Solution Explorer via the properties grid for the FSharp.Core reference:
For library components that must run in many contexts, you can choose the F# 3.0 runtime, though some language features may not be available to you. For applications that take advantage of the most recent language features, you can choose the F# 3.1 runtime.
Better discoverability of online templates
The Visual F# tooling is unusual in that relatively few templates are provided “in-the-box” with Visual Studio. This is deliberate, as it is simpler to provide templates through the Visual Studio Gallery. However, surprisingly few people realize that the online templates are there!
To make things very obvious, we have added a link to the online templates in the “Installed Templates” dialog. This applied to all languages in Visual Studio using this dialog.
Brace completion with smart indent in the editor
Automatic brace-completion is now enabled for many Visual Studio languages, including F#. When you type an opening brace or quotation mark, the closing brace or quote will be automatically inserted for you, leaving the caret between the two. You will see a small blue mark indicating the brace character that was inserted for you:
If you enable “Smart” indentation from the Tools –> Options –> Text Editor –> F# –> Tabs menu, you will get automatic indentation when hitting enter between auto-completed braces.
Hitting “return” from here:
Results in:
Supported brace-types for F# are [ ], ( ), { }, and “ “.
Tooltips and Go To Definition for operators
Tooltips and “go to definition” (F12) are now provided for operators:
Internal engineering work to allow more frequent updates
Behind the scenes, the Visual F# team has also been doing considerable work to allow the Visual F# tooling to be updated more frequently, and independently of Visual Studio. This is an important direction for many Visual Studio components and promises more flexibility in release and development cycles, while maintaining high quality levels.
Other major improvements in Visual Studio
F# programmers using the Visual F# tools also benefit from many of the great general improvements made in the .NET 4.5.1 and Visual Studio 2013 pre-release. You can find out more about these in Brian Harry’s blog on Application Lifecyle improvements, and S. Somasegar’s blog on Visual Studio 2013 announcements at TechEd 2013.
Feedback
The Visual F# team and the designers of F# want your feedback on F# 3.1 and the latest Visual F# tools! Use any of the following channels to report bugs or log suggestions:
- fsbugs@microsoft.com– Send F#-specific bug reports directly to the Visual F# team via this address. This is the quickest, easiest way for the team to collect community bug reports.
- Connect– A long-standing Microsoft channel for bug reports and suggestions, Connect is the perfect place to log bug reports for issues you encounter anywhere in Visual Studio 2013 Preview.
- Send-a-Smile/Send-a-Frown – A very lightweight way to send quick feedback (good or bad) on anything you notice in Visual Studio 2013 Preview. Look for the smiley- and frowny-face icons in the upper right corner of the Visual Studio window.
- MSDN Forums
- UserVoice
If you would like to know more about F# or the Visual F# tools, please visit the following:
Please also follow us on twitter.