다음을 통해 공유


Announcing a pre-release of F# 3.1 and the Visual F# tools in Visual Studio 2013

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.

[ Update: When using pattern matching with multiple fields, use semicolons, e,.g. Prism(width=w; height=h) ]

31blog_1

 

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: https://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<T>(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:

 [<Extension>]
 type ExtraCSharpStyleExtensionMethodsInFSharp () =
  [<Extension>]
 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:

 [<Literal>]
 let test1 = "a" + "b"
 [<Literal>]
 let test2 = 1 ||| 64
 [<Literal>]
 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:

 

31blog_2

 

The same capability is present directly from Solution Explorer via the properties grid for the FSharp.Core reference:

31blog_3

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.

31blog_4

 

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:

31blog_5

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:

31blog_6

Results in:

31blog_7

 

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:

31blog_8

 

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.

Comments

  • Anonymous
    June 27, 2013
    Wow. Simply. Amazed. Was not expecting this, very excited!

  • Anonymous
    June 27, 2013
    Too bad those guys over in the SQL team killed Cloud Numerics, because if they had not then you could actually do something useful with those matrices you are showing off here.

  • Anonymous
    June 27, 2013
    Way cool! I'm really happy you guys keep grinding out improvements and features for F# and its toolchain.

  • Anonymous
    June 27, 2013
    Congratulations on the good work supporting the F# language.

  • Anonymous
    June 27, 2013
    Named discriminated unions are great! Thanks! But it doesn't seem to work with pattern matching though? Especially when pattern matching, named parameters would greatly improve the readability of the code. Something along the lines of: type TestUnion = Test of A : int * B : int [<EntryPoint>] let main argv =    let d = Test(B = 1, A = 2)    match d with    | Test(a = A, b = B) -> a + b // Test(A = a, B = b) or Test(a : A, b : b) also does not work    | _ -> 0

  • Anonymous
    June 27, 2013
    Hi, I've just installed VS 2013 Premium Preview but there's no FSharp section in other languages. I'm running on Windows 8.1 Preview. Where's my F#?

  • Anonymous
    June 27, 2013
    Axel, the syntax for pattern matching on named union fields seems to call for a semicolon separator instead of a comma, e.g. Test(A = a; B = b) while tuple-style (comma separator) pattern matching continues to work on unions with named fields as well, e.g. Test(a,b) Kinda of weird but I guess symmetric with pattern matching on record fields.

  • Anonymous
    June 29, 2013
    The comment has been removed

  • Anonymous
    June 30, 2013
    Wow. Great job!

  • Anonymous
    July 03, 2013
    As at least one other person has pointed out, F# desperately needs better tooling. The two things I really miss when I'm coding in F# are refactoring and Go-To-Definition (where the definition is in another language, even if it's in the same solution). F# is really darned cool, but you've got millions of C# coders around the world who've gotten spoiled with the really wonderful tooling available for them - and you're going to have a hard time convincing them to switch if the tooling for F# remains second-rate.

  • Anonymous
    July 12, 2013
    Wow. Simply. Amazed. Was not expecting this, very excited!

  • Anonymous
    August 30, 2013
    Please please please, give us GO TO DEFINITION in F#

  • Anonymous
    November 07, 2013
    The comment has been removed

  • Anonymous
    November 23, 2013
    Language itself is matured, but not it's VS tooling. nor the MS's attitude. MS's strongly restricted use of F# seems totally irrational. But if you do know F# then you don't want to use any of the C clones, and a questions arise: why is Typescript and not Funscript. where is the F# express ets.

  • Anonymous
    December 24, 2013
    Can this be downloaded for VS 2012?