Detailed Release Notes for F#


The full change list for F# is below. Here’s the list of fixes we’ve made between F# and F#
    —   Permit the use of lambdas taking multiple tupled arguments within quotations.
    —   Fix integer formats 0b101001 and 0o101030 in fsi.exe (thanks to Robert Pickering for this one)
    —   Fix inlining of composition operator
    —   Add signature to ‘prim-types’, hiding the presence of the “Basics” module (thanks to James Margetson and Richard Mortier for this one)
    —   Fix optimization of integer keys for hash tables

Changes for F#

F# Language: Namespaces.. Multiple namespaces fragments now permitted in a single file. Multiple fragments can also be constrained by a single signature. Multiple different files within an assembly may also contribute to the same namespace. For example:

  /// Put the concrete type definition under ‘Types’
namespace Microsoft.FSharp.Math.Types

type BigComplex = { r: bignum; i: bignum }

/// Now add a type abbreviation and module under the main namespace
namespace Microsoft.FSharp.Math

type bigcomplex = Microsoft.FSharp.Math.Types.BigComplex
module BigComplex = begin
open Microsoft.FSharp.Math.Types
let complex r i = { new BigComplex with r=r;i=i }

F# Language: Use of null values no longer require type annotations. null values previously required immediate type information. Instead, null constraints have now been incorporated into the inference process, meaning that the type associated with the use of the null value must simply be resolved at some point in the type inference scope. This means far fewer type annotations are needed when passing ‘null’ values to .NET.

F# Language/Library: Implementation of Structural comparison, equality and hashing now in F# code (hence easier to understand and debug). See the file prim-types.fs in the library for the implementation of the definition of structural and physical equality, used if all other optimization techniques fail.

F# Language: More General Type Checking Rule for Class Field Access and Setting. Accessing and setting a class field previously required the object being accessed to have precisely the type of the class containing that field. This has been liberalized so that the object can have any subtype of the class containing the field. This change may affect code that uses signatures, because the inferred type of a function may be more general. For example, given

  type MChan =
val mutable sndLst : MChan list

let linkMChan src dstLst = src.sndLst <- append src.sndLst dstLst

the inferred type of linkMChan was previously

  val linkMChan : MChan -> MChan list -> unit

but is now the more general

  val linkMChan : #MChan -> MChan list -> unit

where as usual the # indicates that any subtype is accepted as the first argument. If no subtyping is required then a rigid type annotation may be used in the implementation:

  let linkMChan (src : MChan) dstLst = src.sndLst <- append src.sndLst dstLst

F# Language: Overload Resolution when Multiple Overloaded Operators Exist. Some .NET types support multiple overloads for the same operator, which must be resolved according to a process similar to the resolution of overloaded methods. F# uses constraints to handle operator overloading, and now resolves the choice between multiple overloads using essentially the same technique as is used to resolve method overloading. For example, the following overloads now resolve correctly:

  let f1 (x:DateTime) (y:TimeSpan) : DateTime = x – y
let g1 (x:DateTime) (y:DateTime) : TimeSpan = x – y
// Return type is also sufficient:
let f2 (x:DateTime) y : DateTime = x – y
let g2 (x:DateTime) y : TimeSpan = x – y
// Just argument types are also sufficient:
let f3 (x:DateTime) (y:TimeSpan) = x – y
let g3 (x:DateTime) (y:DateTime) = x – y

F# Language: Type Qualified Disciminator Names. Ambiguity between constructors of a discriminated union can now be resolved by using the type-qualified path to the discriminator, for example:

    type XY = X | Y
type YZ = Y | Z

let y1 = XY.Y
let y2 = YZ.Y

let f xy =
match xy with
| XY.X -> “X”
| XY.Y -> “Y”

let g yz =
match yz with
| YZ.Y -> “X”
| YZ.Z -> “Y”

The same is true of record field names, though this has been the case for some time now.

New F# Samples: DirectX 3D Visualization, WebCrawl. See the ‘samples’ directory.

F# Library: Warnings now given that ‘Stream’ will be renamed. This module has been renamed ‘LazyList’.

F# Library: BigNum performance improvements. Major implementation improvements and tuning the cross-over between the multipliers.

F# Library: Additional Math.Complex operations.

F# Interactive and Library: Default floating point format for generic printing now ‘g10’. i.e. for print_any, output_any, etc. and F# Interactive.

F# Interactive: –codepage switch now accepted by fsi.exe. This controls the codepage used to read the input files. The switch does not yet apply to fsc.exe.

F# Library: Primitive structural comparison and hashing routines moved. These were in Microsoft.FSharp.Primitives.CompilerPrimitives but are now under Microsoft.FSharp.LanguagePrimitives. After a review of the library and as part of the re-implementation of structural comparison and hashing in F# code (see below) the primitive functions used for polymorphic recursive calls in structural comparison and hashing have been moved to a new module Microsoft.FSharp.LanguagePrimitives. These functions may have been called recursively from some user code. The section in the language specification has been updated to reflect this.

F# Compiler: Optimizations and Code Quality. Fewer locals are now produced in many situations where inlining occurs. This improves the quality of the end x86 code, allows the JIT to inline more often and reduces the size of the metadata in generated assemblies.

Extensible expr.[idx] syntax for string, array, dictionary and other access operations.. The syntax expr.[idx] is now shorthand for accessing the Item property on a type. This means that expr.[idx] can be used to perform lookups on essentially any .NET collection type.

Note: As with overloaded operators on integers, the types string and the array types do not in reality support Item properties in the underlying .NET metadata. However F# arranges things to give the appearance that they do.

F# for Visual Studio: Minor improvements

  • Type hints in Visual Studio for members (hover over members shows the inferred types)
  • Numerous other minor fixes
  • Script, Yacc and Lex F# file types are available as new files in F# Projects in VS2005 and VS2003.

F# Interactive: Suffixes .fsx and .fsscript now accepted.. These are useful for F# Interactive scripts.

F# Interactive: Formatting options may now be specified. There is an fsi object, of type InteractiveSession, available in the top-level.

  namespace Microsoft.FSharp.Compiler.Interactive
type InteractiveSession
member FloatingPointFormat: string with get,set
member FormatProvider: System.IFormatProvider with get,set
member PrintWidth : int with get,set
member PrintDepth : int with get,set
member PrintLength : int with get,set
member ShowProperties : bool with get,set
member ShowIEnumerable: bool with get,set
member PrintIntercepts: (StructuredFormat.IEnvironment -> obj -> StructuredFormat.Layout option) list with get,set
member AddPrinter: (‘a -> string) -> unit


Here’s an example of it’s use:

  > fsi;;
> fsi.FloatingPointFormat <- “%.3”;;
> fsi.PrintWidth <- 80;;
> fsi.AddPrinter(fun (x:System.DateTime) -> sprintf “%Ld” x.Ticks);;
> System.DateTime.Now;;
> fsi.ShowIEnumerable <- false;;
> fsi.ShowProperties <- false;;

F# Compiler: The –base-address flag. Base addresses indicate the default loading address for DLLs within a memory space. Loading a DLL at a default location can reduce the need for ‘fixups’ that occur when a native DLL gets relocated. Native DLLs occur with F# code if you use NGEN with your F# DLLs, and it is recommended that you use an appropriate base address if rebasing conflicts occur when using NGEN. Various tools and debuggers are available on the web to help determine if rebasing is occuring.

F# Compiler and F# Interactive: Use F# with Microsoft internal or self-built versions of the CLI. Some Microsoft internal or self-built implementations of the CLI have unusual, non-standard names such as v2.0.x86chk. The –cli-version flag can now be used to specify such a version.

F# Interactive: Minor improvements

  • Include paths and current directory context now used to resolve #load and #use directives in F# Interactive.
  • Line numbers and file names now passed with fragments of code executed in Visual F# Interactive.
  • Current Directory Context now passed with fragments of code executed in Visual F# Interactive.
  • FSI in Visual Studio (ALT-ENTER) supports history (up/down) and clear (from context menu)

Minor improvements and Bug Fixes

    574	F# Compiler	issue with top level mutables (fsi.exe), reported by Andrew Fitzgibbon
389 F# Perf Printf implementation allocated too many closures
594 F# Compiler tyvar lookup failed in ilreflect
595 F# Interactive F# Interactive code generation bug when closures used inside interface implementations
596 F# Interactive F# Interactive code generation bug: Implementing generic interfaces does
not always correctly work around Reflection.Emit limitations
586 F# Compiler local mutables spilled into other locals prior to use
588 F# Compiler expr of constructor argument is not typed-expr
587 F# Compiler poor error message on for i = 0 to 10 do .. done expr
590 F# Compiler match exprA,exprB with …. allocates tuples
592 F# Compiler poor error message when a constructor is too generic
582 F# Compiler fsi prints types of the latest interaction with full path
581 F# Compiler Problem with pickling: Quotation <@ 1.3 @> gives NaN
576 F# Perf Reduce number of generated IL locals
566 F# Compiler interface inheritance/extension not being printed correctly
471 F# Compiler Eliminate unnecessary .cctors
— Fixes to printing and Array2 module for non-zero-bounded multi-dimensional arrays.
— Instance members now permitted on types that may use null as a representation. They
are compiled as static members.
— Fields in super classes not accessible (reported by Ralf Herbrich – thanks Ralf!)

Comments (1)

  1. As reported by the Hub Father, F# is available. This is a &quot;release candidate&quot;, which means we put it up to see if it meets the standards of the early adopters who download and install it.  Since posting on Friday we’ve had a few very