F#, the F# Compiler and the F# Visual Extensions, Version 1.1.12.3

Welcome to F#. F# is a programming language for the .NET platform with a design based on the ML programming language with extensions to access .NET libraries. This release contains

Full details can be found at the F# website. There you can find details about how to join the F# email list. You may be interested in tracking Don Syme's F# blog and/or blogging about your experiences with using F#.

Installation:

Using and Learning:

Troubleshooting:

Requirements

Using F# with Mono

You may run F# programs in conjunction with other CLI implementations such as Mono. Please read the notes below. Some more information is available at the F# Wiki.

Changes

Collected changes between v1.1.11.12 and 1.1.12.2

Lightweight syntax option. Are you sick of writing in? The #light option makes the use of certain keywords such as in optional by using indentation. See the informal language specification for details, as well as the ConcurrentLife sample and the Samples101 tutorial. Enable using #light.

First experimental cut at the Active Patterns. More details to follow on Don Syme's blog.

More modules in MLLib. Modules UInt8, Int8, Int16, UInt16 have been added.

More collections in Microsoft.FSharp.Collections. The Set and Map collections are now defined as object-oriented abstractions in Microsoft.FSharp.Collections. The corresponding MLLib modules are defined in terms of these OO abstractions.

Removed deprecated Stream module from MLLib. Minor updates to the LazyList module as a result.

--gnu-style-errors flag no longer accepts spurious integer argument.

Slight modification to overloading for +,*,/,mod.

In version 1.1.11 a slight change was made to the default overloaded signature for - operator to allow the return type to be unassociated to the two input types, as is required for overloading on the System.DateTime subtraction operator. This change was mistakenly applied to other operators, resulting in situations where type inference would report unexpected inference errors for fairly straight-forward floating point code.

Bug fixes.

    ---	F# Compiler	-R clobbers DLLs with PDBs
    ---	F# Compiler	no properties being generated for top level values
    605	F# Visual Studio VFSI scroll to caret does not always show input position
    643	F# Compiler	internal warning when unpickling override of abstract member
    655	F# Compiler	interface implementing methods marked private but included in modul_typ
    656	F# Compiler	Runtime exception TypeLoadException method 'Specialize'... tried to implicitly override a method with weaker type parameter constraints
    645	F# Debug	problems setting breakpoints in inner functions (reported by Jack Palevich - thanks Jack!)
    647	F# Compiler	lowercase constructors are incorrectly permitted
    654	F# Interactive	cannot declare delegate types interactively
    672	F# Visual Studio Unapplied methods should give signature of method overloads in error message
    671	F# Compiler	-R feature overwrites .dll file with .pdb file
    670	F# Compiler	protected access not permitted via member 'this' variables
    668	F# Language	L-R type inference with (fun x -> x * x * 1.0)
    667	F# Language	exceptions to carry line numbers?
    663	 Fix broken codegen for generalized constrained polymorphic functions
    659	F# Visual Studio Intellisense does not work in a for .. to .. do line
    676	F# Visual Studio Inappropriate popup
    644	F# Language	execution and inference for record expressions is not always left-to-right
    533	F# Release	proper uninstaller
    517	F# Compiler	fsi.exe does not process #r/#I directives for files on command line
    678	F# Library	delete very old obsolete functionality fro the 'Set' module
    679	F# Library	Add object-oriented version of immutable 'Sets' to Microsoft.FSharp.Collections
    681	F# Visual Studio hardwhite intelisense
    682	F# Compiler	field and property names with same name - allowed
    680	F# Visual Studio intelisense bugs
    665	F# Language	exprs ending in semi-expr sequences cause confusion when ending constructs which are themselves semi separated.

Changes between v1.1.11.7 and 1.1.11.12

Copy-Local reference options DLLs that are not in the GAC must be copied to an application's directory prioer to execution. This is not currently well-supported by the F# Visual Studio mode. Thus the following options are now supported by the fsc.exe compiler and are especially recommended for use from Visual Studio:

  -R           DLL     both reference the given DLL and copy it to the output directory at the end of compilation
  --copy-local FILE    copy the given file to the output directory at the end of compilation

Note that -R = -r + --copy-local. Also these switches are not required by fsi.exe which is able to resolve and load DLLs from any location.

New Installer InstallFSharp.msi. This currently always installs to the Program Files directory.

New library module Microsoft.FSharp.MLLib.Native Helpers for native interop. See library documentation.

Minor breaking change for native pointers. The F# "'a nativeptr" is now compiled as the .NET type System.IntPtr for all 'a. .NET pointers such as "int*" are now represented by "ilsigptr" types. This cange is because although .NET has a notion of a "pointer type", used in some .NET signatures, these are not "real" types, since they can't be used within generic instantiations. This is very bad for C-interop F# code, which generates generic instantiations for function and tuple values. Thus, the F# 'a nativeptr type is now always compiled as System.IntPtr, regardless of 'a (it is not type equivalent as far as F# is concerend - this is just how the type is compiled. The pseudo-type 'a ilsigptr (IL Signature Pointer) is provided if you need to call a .NET signature using a pointer type.

COMPILED and INTERACTIVE supported as standard --define in F# Interactive and compiled code This is useful as some code fragments such as Application.Run() are only needed in compiled code. Also accessing things such as resources can vary between interactive and compiled code.

Type Inference corrections for fields and records

It is implicit in the F# informal specification that record constructions should use contextual left-to-right type information to help determine the type being constructed. This is now implemented, and makes it easier to use record syntax when record member names overlap.

Types are no longer inferred from uses of class field labels alone. Previously, defining a class "C" with a value field called, say "f" meant that "f" became a scoped record label. This meant that "expr.f" would infer the type of "expr" to be "C". This is still done for _record_ labels, but is no longer done for class field labels, and instead an annotation may be needed to constrain the type of "expr" based on left-to-right type inference. A helpful warning about the deprecation of this language feature is given when this occurs. This was always meant to be the intended treatment of inference for these constructs - it was an artefact of the initial implementation that inference for record field labels was treated in this way.

Various .NET generic constraints implemented .NET generics supports a number of somewhat adhoc constraints on the structural properties of types. It is necessary for F# to support these in order to emit correct and valid generic code and make sound use of F# libraries. The syntax of the constraints is:

   when 'a : struct       // any struct, with the exception of Nullable
   when 'a : not struct   // any reference type - note - this syntax is under revision
   when 'a : (new : unit -> 'a)   // default constructor

The following F#-specific constraint has also been added:

   when 'a : null          // any reference type that supports null according to the F# pseudo-enforcement rules for prohibiting the use of null with F# types
   when default 'a : <type>  // the variable will take the given value if not otherwise instantiated or generalized

Default constructors are called using the syntax:

   new 'a()

Where 'a should be related to another annotation in the same definition, e.g. an argument of the enclosing function. This constructs is compiled as a call to System.Activator.CreateInstance<'a>().

Minor improvements and Bug Fixes

   573	F# Compiler	list equality is not tail recursive.
   613	F# Library	List.combine and List.split are not tail recursive (reported by Ralf Herbrich - thanks Ralf!)
   615	F# Interactive	FSI reflection code throws TypeLoad error for type reference within the same interaction.
   602	F# Compiler	name of type not reported in "member required" error
   120	F# Compiler	Things stored in public static fields should only be accessible via properties
   495	F# Compiler	SQL cannot load F# assemblies due to publically writable statics
   625	F# Compiler	Poor error location for error messages related to 'new' in signatures
   626	F# Library	Add 'generate' methods to IEnumerable.
   628	F# Compiler	nested ifdefs not always handled correctly (Reported by Jack Palevich - thanks Jack!)
   630	F# Compiler	Error writing assembly with F# 1.1.11.7 (reported by Lewis Bruck - thanks Lewis!)
   631	F# Compiler	System.MethodAccessException thrown by FSI.EXE (reported by Pierre Dangauthier - thanks Pierre!)
   634	F# Compiler	object expression limitations: let bound object expressions not generalized (reported by Greg Neverov - thanks Greg!)
   640	F# Compiler	record fields should be inferred from the known context type of the expression 
   639	F# Compiler	class fields are contributing to the record field environemnt
   638	F# Compiler	multiple constraints on type parameters not being correctly printed
   636	F# Compiler	simple object expressions implementing interfaces should be allowed in "let rec" without generating an iniitalization graph warning
   632	F# Debug	smoother debugging needed for inner recursive functions
   648	F# Library	Documentation for printf codes for 64-bit integers is incorrect (reported by Richard Mortier - thanks Richard!)
   650	F# Compiler	incorrectly permitting the declaration of interfaces that contain fields (reported by Robert Pickering - thanks Robert!)
   649	F# Compiler	bug in quotation template filling for typed quotations (Reported by Tomas Petricek - thanks Tomas!)
   646	F# Compiler	attributes on top level values not propagating to generated static fields, e.g. ThreadStatic (reported by Robert Pickering - thanks Robert!)
   645	F# Debug	setting breakpoints in inner functions sort of broken (reported by Jack Palevich - thanks Jack!)

Changes between v1.1.11.6 and 1.1.11.7

Minor improvements and Bug Fixes

    --   Fix to permit the use of lambdas taking multiple tupled arguments within quotations.
    --   Fix integer formats 0b101001 and 0o101030 in fsi.exe
    --   Fix inlining of composition operator
    --   Add signature to 'prim-types', hiding the presence of the "Basics" module
    --   Fix optimization of integer keys for hash tables

Changes between v1.1.10.3 and 1.1.11.6

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 }
  end

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 = 
    class
       val mutable sndLst : MChan list
    end

  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

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 
    with
      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
      ...
    end

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

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!)

Changes between v1.1.10.2 and 1.1.10.3

The 'a nativeptr type. The unverifiable type constructor nativeptr is now supported for C/C++/C# pointer types, e.g. sbyte* becomes sbyte nativeptr. In principle this is a breaking change, as previously .NET pointer types were mapped to the F# type nativeint, and are now mapped to nativeptr instead. The new behaviour is, however, consistent with .NET and necessary to permit methods that overload by pointer type (e.g. the unverifiable System.String constructors accepting byte pointers) to be resolved correctly.

Minor improvements and Bug Fixes

Changes between v1.1.9.1 and 1.1.10.2

F# Interactive for Visual Studio. It rocks! See the section above.

F# website now at http://research.microsoft.com/fsharp

Unified, first-class, composable events. .NET events can now be accessed directly through their real name (e.g. form.Click) rather than through their helper functions (form.add_Click etc.). They can also be used in a first-class way, i.e. form.Click can be passed around as a value. The type of such a value is Idioms.IDelegateEvent, which extends Idioms.IEvent. F# published delgate types should have type Idioms.IHandlerEvent. An MLLib module Microsoft.FSharp.MLLib.IEvent includes some basic polymorphic operations over IEvent types.

Quotation processing over raw quoted expressions. New quotation operators such as <@@ @@> are supported for quoting terms (expressions) in their raw form. More details can be found in the documentation on the Quotations module and the F# informal language specification.

Removed Drop-Down VS Discrimination Menus. Temporarily disabled discrimination drop-down Intellisense in VisualStudio, due to poor completions.

Minor improvements and Bug Fixes

Changes between v1.1.8.1 and 1.1.9.1

Minor improvements and Bug Fixes

Minor syntax extension related to struct. The syntax module X = begin ... end can now be used in addition to the OCaml-compatible syntax module X = struct ... end. The use of the word struct is potentially ver confusing to .NET-savvy newcomers, who will confuse this with a C# struct. Likewise module X : begin ... end is now the recommended way of writing module X : sig ... end in signatures.

Address-of operator. Occasionally a need arises to pass a byref parameter on to a function. This can now by done using the '&expr' address-of operator. A warning will be given whenever this is used.

Source cleanup. Various cleanup work items completed.

ExportAs deprecated. ExportAs was an old, somewhat half-baked technique to export functions as classes. Now that the object model has been implemented it is no longer needed.

Changes between v1.1.7.0 and v1.1.8.1

Matrix library redesign and cleanup. Microsoft.FSharp.Math has been reorganised.

Expression quotation library redesign and cleanup. Now called Microsoft.FSharp.Quotations.

HTML library manual pages now included in the release and on the Microsoft Research website.

HTML documentation generation with fsc.exe. Look for the --html* flags in the advanced flags. Documentation is given using "///" comment markers prior to modules, types, values and exceptions.

Fix some problems with the Visual Studio mode. Some files were missing.

Changes between v1.1.5.2 and v1.1.7.0

Expression Quotation. Microsoft.FSharp.Experimental.Lifted (NOTE later renamed to Now called Microsoft.FSharp.Quotations) contains a range of functionality related to "lifted expressions", i.e. expression quotation, which is a form of meta-programming. This is still under development, and some important functionality is missing or incomplete, but is extensively used in the LINQ sample that is also available in the release.

LINQ Sample. The sample samples\fsharp\FLinq shows how F# can work with the Language-Integrated-Query libraries currently under development at Microsoft.

Source Release. source/... now includes the source code to the Abstract IL, ILX, the F# compiler, F# interactive, the library and the tools, as long promised.

Compiling: To compile it up you us the Makefile and the F# compiler from the distribution itself, and you currently need .NET 2.0, and there is some C/C++ helper code to compile which requires the use of the Microsoft Visual Studio 2005 C/C++ compiler. However you do not really need to compile the C/C++ code, which only enables debugging support etc. (and indeed you can reuse the absilsuppc.dll from the F# distribution itself instead of compiling it up afresh). It should be fairly straightforward to compile with .NET 1.0/1.1 (--cli-version 1.0, change define GENERICS to NOGENERICS etc.) and should also be possible to compile on Mono using 'fscp10ntc.exe', the portable bootstrapped compiler.

General comment: The source has its many quirks and there are many things in we will be cleaing up - if it's ugly then please be merciful and ignore it. Anyway, have fun with it!

Visual Studio mode: (The source for the VS plugin is not yet included, though a crucial file 'fsharp/vs/service.ml' is - this has the key functionality that implements the line-by-line lexing, typechecking cache etc.)

Argument name annotations for documentation purpose in signatures. Arguments can be labelled for documentation purposes, in signature files (.mli/.fsi) only. Note this is not the same os OCaml labelled arguments (which permit labels to be used at the callsite). For example:

    val open_in_gen: flags:open_flag list -> permissions:int -> filename:string -> in_channel

First class uses of the 'unit' type now compiled to Microsoft.FSharp.Unit. Previous versions of F# compiled the unit type to System.Object. This has been changed to give better fidelity for runtime types, especially of function values. Note this will break C# 2.0 code that has not been using delegates of type System.Action</tt> as the way of creating function types.

Library Updates.

1.       Adjust the signature of Idioms.using.   

The current signature of Idioms.using is

val using: (_ :> System.IDisposable) -> (unit -> 'a) -> 'a

giving somewhat awkward usage patterns such as

let ts = new TransactionScope() in

using ts (fun () ->

      <do something with ts>

)

In this release the signature becomes

val using: ('a :> System.IDisposable) -> ('a -> 'b) -> 'b

giving considerably more C#-like usage patterns such as

using (new TransactionScope()) (fun ts ->

      <do something with ts>

)

When translating code from C# we have found ourselves defining a new version of “using” to match the above, so it seems preferable, and something we should switch to sooner rather than later.

2.       Standardize on the frequent use of “|>”

  

The operators “|>” and “>>” are already defined in MLLib.Pervasives as follows:

let (|>) x f = f x

let (>>) f g x = g (f x)

Over time it has become clear that use of these operators, and the “|>” operator in particular, is key to succinct expression of functional programming when using left-to-right type inference to resolve some name access base on type information (the technique F# uses to resolve method overloading and property accesses). Thus we will be using this operator far more extensively in F# code, tutorials and samples, and will assume that it’s use one of the first things an F# programmer learns.  

For example, note how “a” and “ty” do not require type annotations in the following code to resolve the use of the “.” notation.  This is because type information is propagated from the result type of GetAssemblies through to these binding sites.

  

let allMembers =

    System.AppDomain.CurrentDomain.GetAssemblies()

    |> Array.to_list |> List.map (fun a -> a.GetTypes()) |> Array.concat

    |> Array.to_list |> List.map (fun ty -> ty.GetMembers()) |> Array.concat;;

(Now write that program in any other .NET language in 4 lines!)

Assuming familiarity with “|>”has some ramifications for library design, leading to some of the changes.   In particular:

·         Delete ‘transform’, ‘foreach’ etc. in MLLib.List, MLLib.Array etc.     These functions were added in an attempt to give left-to-right type inference, in the style above.  However, they were never terribly effective at doing this.  Furthermore the use of the name “foreach” clobbered the corresponding name in Idioms. They are best forgotten.

  

3.       Include decent support for IEnumerable-related functions

·         Add the following modules to MLLib (NOTE: not all functions are supproted in this release)

  

module IEnumerable

// The following functions work over the System.Collections.Generic.IEnumerable type

val length   : #IEnumerable<'a> -> int

val hd      : #IEnumerable<'a> -> 'a

val tl      : #IEnumerable<'a> -> IEnumerable<'a>

val nth     : #IEnumerable<'a> -> int -> 'a

val nonempty: #IEnumerable<'a> -> bool

  

val empty : unit -> IEnumerable<'a>

val init    : (int -> 'a option)                         -> IEnumerable<'a>

val unfold   : ('b -> ('a * 'b) option) -> 'b -> IEnumerable<'a>

val append  : #IEnumerable<'a> -> #IEnumerable<'a> -> IEnumerable<'a>

val concat   : #IEnumerable< #IEnumerable<'a> > -> IEnumerable<'a>

  

val exists   : ('a -> bool)               -> #IEnumerable<'a> -> bool

val for_all : ('a -> bool)               -> #IEnumerable<'a> -> bool

val filter   : ('a -> bool)               -> #IEnumerable<'a> -> IEnumerable<'a>

val choose   : ('a -> 'b option)     -> #IEnumerable<'a> -> IEnumerable<'b>

val first   : ('a -> 'b option)     -> #IEnumerable<'a> -> 'b option

val find    : ('a -> bool)               -> #IEnumerable<'a> -> 'a

val tryfind : ('a -> bool)               -> #IEnumerable<'a> -> 'a option

  

val iter    : ('a -> unit)               -> #IEnumerable<'a> -> unit

val iteri   : (int -> 'a -> unit) -> #IEnumerable<'a> -> unit

val fold    : ('b -> 'a -> 'b) -> 'b -> #IEnumerable<'a> -> 'b

val map     : ('a -> 'b)          -> #IEnumerable<'a> -> IEnumerable<'b>

val mapi       : (int -> 'a -> 'b)   -> #IEnumerable<'a> -> IEnumerable<'b>

  

val of_array: 'a array                 -> IEnumerable<'a>

val of_list : 'a list                   -> IEnumerable<'a>

val to_array: #IEnumerable<'a> -> 'a array

val to_list : #IEnumerable<'a> -> 'a list

// The following functions work over the System.Collections.IEnumerable type

// and are available on .NET 1.0/1.1

val untyped_fold  : ('b -> 'a -> 'b) -> 'b -> #IEnumerable -> 'b

val untyped_iter  : ('a -> unit)                     -> #IEnumerable -> unit

val untyped_map   : ('a -> 'b)                         -> #IEnumerable -> IEnumerable

val untyped_filter: ('a -> bool)                     -> #IEnumerable -> IEnumerable

val untyped_to_list:                          #IEnumerable -> 'a list

·         Mark the following as obsolete. 

Idioms.foldeach         (replaced by IEnumerable.fold_untyped)

Idioms.transform        (replaced by IEnumerable.map_untyped)

Idioms.foldeachG        (replaced by IEnumerable.fold)

Idioms.transformG             (replaced by IEnumerable.map)

Idioms.foreachE                 (never needed – all relevant types implement IEnumerable)

Idioms.foldeachE        (never needed – all relevant types implement IEnumerable)

Idioms.transformE             (never needed – all relevant types implement IEnumerable)

Idioms.foreachEG             (never needed – all relevant types implement IEnumerable)

Idioms.foldeachEG       (never needed – all relevant types implement IEnumerable)

Idioms.transformEG           (never needed – all relevant types implement IEnumerable)

                        This leaves the following in Idioms:

val foreach : #System.Collections.IEnumerable             -> ('a -> unit) -> unit

val foreachG: #System.Collections.Generic.IEnumerable<'a> -> ('a -> unit) -> unit

  

Rationale: The purpose of Idioms is to hold F# representations of idioms in .NET, C# and other languages. It should be comprehensible to beginner F# users.  The above functions were added in a bit of a hurry and simply shouldn’t be in Idioms, since their purpose is to offer a consistent set of folding and mapping operations over both the generic and non-generic (untyped) IEnumerable and IEnumerator types. Much preferable is a module in MLLib that holds these operations using the consistent MLLib naming scheme (iter, fold, map etc.).  

  

Note: the LINQ initiative will offer further platform-standard functionality similar to the above, and when the final version of LINQ is released we will support a namespace such as Microsoft.FSharp.Bindings.Linq which maps the Linq operators into F#.  Having a half-baked version of this stuff in Idioms doesn’t do anyone any good.   However we can’t wait for the release of Linq to fix this sort of thing, and in any case Linq uses naming conventions which are different to F# (select for map, where for filter etc.).

·         Mark as obsolete the very thinly populated and undocumented Idioms.IEnumerable, Idioms.IEnumerator.   These were again added in a hurry leading up to the last release and are again best forgotten.

4.       Include consistently named support for Enum-related functions

  

·         Add the following module to MLLib

  

module Microsoft.FSharp.MLLib.Enum

  

///Convert an enumeration value to an integer.  The argument type is inferred from context.

val to_int: 'a -> int             when 'a :> System.Enum

///Convert an integer to an enumeration value.  The result type is inferred from context.

val of_int: int -> 'a             when 'a :> System.Enum

  

///Combine enum values using 'logical or'. The relevant enumeration type is inferred from context.

val combine: 'a list -> 'a        when 'a :> System.Enum

  

///Test if an enumeration value has a particular flag set, using 'logical and'.

///The relevant enumeration type is inferred from context.

val test: 'a -> 'a -> bool        when 'a :> System.Enum

·         Mark the following as obsolete. 

Idioms.EnumToInt                         (replaced by Enum.to_int)

Idioms.IntToEnum              (replaced by Enum.of_int)

Idioms.CombineEnumFlags             (replaced by Enum.combine)

Idioms.TestEnumFlag                     (replaced by Enum.test)

Rationale: The purpose of Idioms is to hold F# representations of idioms in .NET, C# and other languages. The above functions are not particularly idioms in any other .NET language – they just represent things where you have to be a bit more explicit in F#.   They date from the day when Idioms was a sink for “anything which you needed to do with a runtime check”.   Their naming is not particularly consistent with any other style.   Nor are they particularly easy to find.

It is much preferable to add a module to MLLib that holds these operations using the consistent MLLib naming scheme (to_int, of_int etc.).   

Note: A future version of F# may support + etc. on enum types.

Bug Fixes. Various minor fixes.

511	F# Interactive	1	0	errors raised during optimization exit fsi.exe
522	F# Interactive	1	1	fsi bug with operator names
523	F# Interactive	1	0	Automatic binding to a relative path (or the current directory) fails
532	F# VS Plugin	1	1	VS -I and -r relative paths are relative to somewhat random working directoy of VS process rather than the project/file working directory
534	F# VS Plugin	2	1	off-by-one error in VS mode balloon tips
525	F# VS Plugin	1	1	visual studio prior inputs with unicode signature are not being parsed correctly
537	F# Docs       	1	1	Abbreviated types appearing in XMLDoc files, also 'unit'
543	F# Language	1	1	printing "List" and "Option" for types generated by uses of constructors looks gross
433	F# Compiler	2	2	Represent "unit" as a real type rather than abbreviating to "obj"
453	F# Compiler	2	2	print_any - no printing of repeated terms - no print depth/width controls
505	F# Language	1	0	implement a way to name arguments - crucial documentation
529	F# Compiler	1	0	differing orders of fields for records in signatures and implementations cause problems for record constructors and "with"
549	F# VS Plugin	1	0	VS redirecting stdout to Output window interferes with stdin
552	F# VS Plugin	1	1	VS mode show 2 resolutions for .NET types
553	F# VS Plugin	1	1	VS Mode method tips bounce back to first entry every time the "down" key is pressed (reported by Artem - thanks Artem!)
554	F# VS Plugin	1	1	Balloon Tips not showing XMLDoc help text for methods and types
555	F# VS Plugin	1	1	Intellisense not showing signatures and overloads for .NET constructors.
556	F# Documents	1	1	Incorrect XMLDoc signatures being generated for generic methods and some other generic gadgets
539	F# Interactive	1	0	compile F# Interactive on .NET 1.0
560	F# VS Plugin	1	1	TAB in VS mode doesn't activate completion
561	F# Language	1	1	Module abbreviations not permitted in signatures
563	Abstract IL	2	2	AbstractIL library contains duplicate hashtable modules etc.
562	F# Library	1	1	printf %s formats do not permit padding specifications
564	Abstract IL	1	1	Abstract IL library module names need to be much more sensibly organized

Changes between v1.1.3.2 and v1.1.5.2

Matrix Library. Microsoft.FSharp.Math.Matrix<_> has been added as a generic matrix type, with extensive MATLAB-like operations at Microsoft.FSharp.Math.MatrixOps<_> and Microsoft.FSharp.Math.MatrixOps.Generic;. The former are for floating point matrices Matrix<float> = matrix, and the latter are generic over all matrix types. The interface to this library is likely to be stable. Vector and RowVector types are also defined - their status sill undergo revision after a few releases.

Very Preliminary Linear Algebra. Microsoft.FSharp.Math.LinearAlgebra<_> contains a handful of basic linear algebra functions.

Compositional, Customizable Structured Printing. A preliminary but powerful approach to user-definable structured display of terms has been implemented in this release. The solution is different to the OCaml-style "Format" library and is instead based on the generation of intermediary "layout" objects. So far, a layout describes how words will fit next to each other and where the breaks (and indentations) will/can be.

A layout engine typically constructs most layouts using a generic algorithm based on the term structure of F# data accessed via Microsoft.FSharp.Experimental.Reflection. Types that wish to customize their structured format specification can implement the StructuredFormat.IFormattable interface, which must provide a function that generates a StructuredFormat.Layout value. An environment is passed to the object that provides a function to use to generate layout for recursive calls. Leaf objects such as numbers and strings can be left unformatted, which gives a formatting engine control over how these appear (e.g. culture specific formatting of numbers). A default formatting engine is provided in Microsoft.FSharp.MLLib.Pervasives.LayoutOps for formatting layouts to strings, channels and text buffers. This engine can be customized to some extent (e.g. by print width, depth, culture and floating-point number formatting) and is used by thw following functions:

as well as the F# Interactive pretty printer. The end result is that objects are converted to textual formats consistently and in a customizable way. Here is and example of the output generated, here for a matrix holding further matrices:

> open Math;;
> open MatrixOps.Generic;;
> let m = matrix [[1.0;2.0;3.0]];;

val m : Matrix

> m;;

val it = matrix [[1.000000; 2.000000; 3.000000]]

> let m = matrix [[m];[m];[m]];;

val m : Matrix<Matrix<float> >

> m;;

val it = matrix
          [[matrix [[1.000000; 2.000000; 3.000000]]];
           [matrix [[1.000000; 2.000000; 3.000000]]];
           [matrix [[1.000000; 2.000000; 3.000000]]]]

Here is an example of customization of the structured layout to format complex numbers, without actually specifying the formats of the constituent components:

open StructuredFormat.LayoutOps
type Complex = { real: float; imaginary: float }
  with 
    member x.r = x.real
    member x.i = x.imaginary
    interface StructuredFormat.IFormattable with
      member x.GetLayout(env) = 
        objL (box x.r) ++ rightL "r" ++ sepL "+" ++ (objL (box x.i) $$ rightL "i")
    end

Named arguments for attributes. Attribute specifications can now take named arguments, e.g.

[<DllImport("KERNEL32.DLL", EntryPoint="MoveFileW",  SetLastError=true,
                            CharSet=CharSet.Unicode, ExactSpelling=true,
                            CallingConvention=CallingConvention.StdCall)>]
let MoveFile ((src : string), (dst: string)) : bool = failwith "extern"

Abstract properties. Interfaces and classes may now define abstract properties and specify overrides and defaults for these. This is functionality that was not completed in the first release of the object model. e.g. in an interface definition:

Abstract properties and properties in interfaces. Interfaces and classes may now define abstract properties and specify overrides and defaults for these. This is functionality that was not completed in the first release of the object model. e.g. in an interface definition:

type IEnvironment = 
  interface
    /// A property indicating the maximum number of columns
    abstract MaxColumns : int
    /// A property indicating the maximum number of rows
    abstract MaxRows : int
  end

And in an implementation by a class:

type MyEnvironment = 
  class C
    interface IEnvironment with
      method x.MaxColumns = 3
      method x.MaxRows = 4
    end
  end

And in an implementation by an object expression:

{ new IEnvironment 
    with MaxColumns = 3
    and  MaxRows = 4 } 

Rename 'MLLib.Vector' to 'MLLib.ReadonlyArray'. 'Vector' and 'vector' are now used for Microsoft.FSharp.Math.Vector, mutable column vectors whose element type typically support certain element operations.

Bug Fixes.

470	F# Compiler	Constructors and method can't be overloaded betweeen 0/1 arguments
473	F# Compiler	Operator overloading bug
474	F# Visual Studio Pattern hints for lists showing operator names, also no testing for these
475	F# Visual Studio Pressing BAR causes poor menus to pop up in Visual Studio too often
478	F# Compiler	#use only processes one interaction per file
479	F# Compiler	fsi - ctrl-C during command line arg processing unhandled.
481	F# Compiler	fsi - syntax error recovery...
482	F# Language	any_to_string doesn't print arrays
483	F# Compiler	internal type variable error (reported by Karthik)
484	F# Compiler	overloaded indexer properties not correctly resolved (from F# Mailing list)
485	F# Compiler	uppercase non-constructor names used in patterns do not give a warning
486	F# Doc   	Fix documentation bug (reported by Greg Chapman - thanks Greg!)
491	F# Library	Equality not implemented on matrices
492	F# Compiler	imperative type vars and type var bindings not being shown in error messages (reported by Karthik)
391	F# Compiler	F# not automatically usable on x64 boxes
372	F# Compiler	F# gives syntax error for OCaml top level expressions 
349	F# Compiler	Inferred constraints of the form "x :> obj" should be ignored (e.g not required in signatures)
250	F# Visual Studio Load on-the-fly XML documentation into Visual Studio, or connect to VS interfaces that will do this for us
309	F# Compiler	import C# constrained polymorphism as F# constrained polymorphism
315	F# Visual Studio output does not go to console window by default
490	F# Library	Consistent approach to structured print layout needed

Changes between v1.1.2.0 and v1.1.3.2

Bug Fixes. Various minor fixes to F# Interactive, e.g. large bytearrays. F# Interactive now works on .NET 2.0 Relase Candidate versions. Additional warnings on some minor incomplete features.

Changes between v1.1.1.6 and v1.1.2.0

Visual Studio. Now supports "Go To Definition" and "Go To Declaration"

MLLib.Printf. Now supports '%M' for decimal values and '%O' for any 'any' object value. These are currently printed using Object.ToString() but may in the future be printed using any_to_string.

Bug Fixes. Visual Studio fixes for '|' triggers.

Core Language. Integer constants for the types 'bignum' and 'bigint' are now supported, e.g.

do Printf.printf "%O\n" 3N
do Printf.printf "%O\n" 3I
do Printf.printf "%O\n" (3N / 4N)
do Printf.printf "%O\n" (3N / 400000000N)
do Printf.printf "%O\n" (3N / 3N)
do Printf.printf "%O\n" (-3N)
do Printf.printf "%O\n" -3N
do Printf.printf "%O\n" (-3N / -3N)
do Printf.printf "%O\n" -30000000000000000000000000000000000000000000000000000000000000N

The following operartors are now supported and can be used for multi-dimensional array lookup/assignment.

   arr.(i,j)          -- Look up a rectangular (non-jagged) 2D array of type 'ty[,]'
   arr.(i,j) <- x     -- Assign into a  rectangular (non-jagged) 2D array of type 'ty[,]'
   arr.(i,j,k)        -- Look up a rectangular (non-jagged) 2D array of type 'ty[,]'
   arr.(i,j,k) <- x   -- Assign into a  rectangular (non-jagged) 2D array of type 'ty[,]'

The MLLib modules Array2 and Array3 provide basic operations for 2 and 3 dimensional arrays. .NET operations on the System.Array type can also be used directly.

Library. The Compatibility.CompatArray and Compatibility.CompatMatrix module now give better results (no polymorphism restrictions apply) if inadvertantly used from .NET 2.0. Use of these modules is not recommended from .NET 2.0 but sometimes occurs when code is copied from cross-compiling samples.

Changes between v1.1.0.4 and v1.1.1.6

Attributes. Specification clarifications for attributes. Attributes now give warnings when used inappropriately. Attributes can now be referenced with or without the Attribute suffix, e.g. [<Obsolete("this function is obsolete")>] or [<ObsoleteAttribute("this function is obsolete")>].

Compilation Speed Optimizations. Improved compilation speeds, especially when using the --standalone flag.

VS Mode. Better response as now compacts less often. Now accepts all fsc.exe flags within the argument window: those irrelevant to type-checking are still used when the command line compiler is invoked.

Minor renamings. The .NET compiled names of some exceptions have changed to follow .NET library design guidelines

The names from F# code are now either the above names or, when using MLLib, the equivalents Assert_failure, Match_failure and Undefined.

Turning off default augmentations for discriminated unions. By default F# dsicriminated unions are augmented with properties and methods such as member IsRed : bool,member Red : int -> Color and Red1 : Color -> int for a constructor Red of int in a type Color. Now that augmenetations are supported directly in the F# language it is often more convenient to manually design these augmentations. The default augmentations can now be suppressed by using the [<DefaultAugmentation(false)>] attribute. For example, the Option<'a> type in the F# library is defined as:

    []

    /// The type of optional values.  When used from other .NET languages the
    /// empty option is the 'null' value.
    type Option<'a> = None | Some of 'a

    /// Augmentation
    type Option<'a> 
      with
        member x.Item = match x with Some x -> x | None -> op_Raise (new System.IndexOutOfRangeException())
        static member IsNone(x : Option<'a>) = match x with None -> true | _ -> false
        static member IsSome(x : Option<'a>) = match x with Some _ -> true | _ -> false
        static member None : Option<'a> = None
        static member Some(x) : Option<'a> = Some(x)
      end

Initial support for Microsoft.FSharp.Experimental.Collections With the completion of the F# support for members and augmentations we are moving the functionality of the MLLib collections to be co-designed libraries for functional and obejct oriented programming. The means that a functional programming API to the collection types will be offfered in MLLib, and a mixed object-oriented/functional API within FSLib. This will greatly improve the usability of the collection types from C# and other .NET languages, without losing the essence of OCaml-compatible ML programming. The first class we have applied this treatment to is Microsoft.FSharp.Experimental.Collections.HashTable and the related HashSet, CHashTable and CHsahSet.

Generic Recursion support temporarily withdrawn. Some bugs were found in the support for generic recursion added in 1.1.0.4 (unverifiable binaries could be produced in some situations). In particular, full signatures need to be given to make a function eligible for generic recursion, and this is not yet enforced. Functions and values may still be given explicit type parameters, but recursive uses of explicitly paramaterized values must at invariant instantiations, as was always the case for versions prior to 1.1.0.4.

Bug fixes. Several bug fixes related to attributes, generalization, enumerators and exception abbreviations, Arg.usage. Thanks to Martin Churchill, Dominic Cooney, SooHyoung Oh, Ondrej Rysavy, Robert Pickering, Greg Lee and Adam Granicz among others for reporting these bugs. Some other bugs recently recorded as fixed in out database are as follows:

443	F# Library  MLLib.Stream incorrect behaviours
442	F# Compiler print_any raises exceptions on singleton constructor values
452	F# Compiler Visual Studio and fsc.exe both have problems with unicode, reported by DOminic Cooney
440	F# Tools    lex/yacc - partial parses of stdin require extra token before succeeding and discard buffered input
441	F# Compiler uncaught exceptions are not reported in user friendly way (no details of what they carry...)
444	F# Compiler records compile to classes with duplicate members names - a problem for debugging
445	F# Compiler serialisation of nil list fails
426	F# Compiler "end of file in string or comment" error doesn't report start-of-string-or-comment
459	F# Compiler Undefined type variable problem
458	F# Compiler typechecker doesn't decode all attributes correctly (decode_simple_cattr_data)
371	F# Compiler Support adding managed resources to .NET DLLs and EXEs
422	F# Compiler VideoPlayer sample gives error
406	F# Library  Bignums package
470	F# Compiler Constructors and method can't be overloaded betweeen 0/1 arguments
467	# Library   any_to_string on char fails on 1.1

Compiler for use with Mono. The binary fscp10ntc is a version of the F# compiler that is reported to work to some extent in conjunction with the Mono CLI implementation. Tailcalls have reported to cause problems on Mono, hence this is a "no tailcall" (ntc) version of the compiler, which leads to changes in performance. The matching "ntc" versions of the libraries are also included. This is also a CLI 1.0 binary, again changing the performance.

This version of the compiler is reported to be sluggish, so a reasonably fast machine may be required. It may also be worth investigating the use of pre-compilation (mono --aot) in conjunction with this binary to improve startup times (pre-compilation is pretty much essential for any compiler).

Changes between v1.0.8.6 and v1.1.0.4

The F# Object and Encapsulation Extensions. F# types can now be augmented with properties, members and operators. Furthermore, .NET-style class and interface types may also be defined in F# itself. Fairly complete documentation is provided in the language specification.

Big integers and arbitrary sized rational arithmetic. The types under Microsoft.FSharp.Math.* are the implementations of the F# arbitrary precision integer and rational arithmetic types. A partially-OCaml-compatible version of this functionality is included in MLLib, i.e. use the functionality available via 'open Num'. The types support overloaded operators. The naturals are used to build arbitrary sized integers and rationals. The implementation aims to for a lower garbage cost and provides multiplication that scales effectively up to huge numbers.

The F# Language Specification (Preliminary). A work-in-progress language specification is now included in the manual.

Specification clarifications.

Managed and Unmanaged Resource Linking. The command-line flags --resource, --link-resource and --win32res are now supported by the F# compiler for embedding native and managed resources (text files, icons, bitmaps, audio files etc.) into executables. They have the same meanings as the corresponding C# flags.

New in Microsoft.FSharp.Idioms. The following are new in this module of useful .NET idioms:

val foreachE: (_ :> System.Collections.IEnumerator) -> ('a -> unit) -> unit
val foldeachE: (_ :> System.Collections.IEnumerator) -> 'acc -> ('acc -> 'a -> 'acc) -> 'acc
val transformE: (_ :> System.Collections.IEnumerator) -> ('a -> 'b) ->  System.Collections.IEnumerator

val foreach: (_ :> System.Collections.IEnumerable) -> ('a -> unit) -> unit
val foldeach: (_ :> System.Collections.IEnumerable) -> 'acc -> ('acc -> 'a -> 'acc) -> 'acc
val transform: (_ :> System.Collections.IEnumerable) -> ('a -> 'b) ->  System.Collections.IEnumerable

#if GENERICS
val foreachG: (_ :> System.Collections.Generic.IEnumerable<'a>) -> ('a -> unit) -> unit
val foldeachG: (_ :> System.Collections.Generic.IEnumerable<'a>) -> 'acc -> ('acc -> 'a -> 'acc) -> 'acc
val transformG: (_ :> System.Collections.Generic.IEnumerable<'a>) -> ('a -> 'b) ->  System.Collections.Generic.IEnumerable<'b>

val foreachEG: (_ :> System.Collections.Generic.IEnumerator<'a>) -> ('a -> unit) -> unit
val foldeachEG: (_ :> System.Collections.Generic.IEnumerator<'a>) -> 'acc -> ('acc -> 'a -> 'acc) -> 'acc
val transformEG: (_ :> System.Collections.Generic.IEnumerator<'a>) -> ('a -> 'b) ->  System.Collections.Generic.IEnumerator<'b>
#endif

type 'a sizeof = { result: int }
val inline sizeof: unit -> $a sizeof


Bugs fixed.

438	F# Compiler	Mixed null and string matches bypassed pattern simplifier
441	F# Compiler	Uncaught exceptions wrapping a string report their message.
442	F# Compiler	Experimental.Reflection failed on singleton constructor values.
	F# VS Mode	Type inference variables appearing in the displayed hover-text for F# values
	F# Library	open_in now opens in ASCII encoding.  Use stream_reader_to_in_channel to open in other encodings

Local names. Improved naming of locals to help during debugging.

Additional Overloading Strings now support overloaded '+'.

Customizable Debugger Views for F# Types. F# types can now be augmented in a a number of ways to customize how the values appear in a debugger. Firstly, the ToString member may be adjusted for each F# concrete type (i.e. record, discriminated union and object types). Secondly, the .NET 2.0 standard DebuggerDisplay attribute can be used in conjunction with member augmentations to customize the simple textual display associated with a type. For example:

type 
 []
 MyIntList =
   | MyNil
   | MyCons of int * MyIntList
 with 
   member x.Length =
      let rec length x acc = match x with MyNil -> acc | MyCons(a,b) -> length b (acc+1) in 
      length x 0
 end

Finally, for sophisticated structured collections the .NET 2.0 standard DebuggerTypeProxy can be used in conjunction with member augmentations to specify a class that represents the visual display of an object. For example:

type 
 []
   MyIntList = MyNil | MyCons of int * MyIntList
and MyIntListDebugView =
   class 
     val v: MyIntList
     new(x) = { v = x }     
     [] 
     member x.Items = 
        let rec length x acc = match x with MyNil -> acc | MyCons(a,b) -> length b (acc+1) in 
        let len = length x.v 0 in 
        let items = Array.zero_create len in 
        let rec go n l = match l with MyNil -> () | MyCons(a,b) -> items.(n) <- a; go (n+1) b in 
        go 0 x.v;
        items
   end

Custom Attribute Extensions Custom attributes now accept 'type' arguments. Double parantheses (to disambiguate the start and finish of the extra argument) and the keyword type must currently be used:

  []

Library additions: Option. The Option module is now a standard part of MLLib. It has a set of functions similar to List.

Library additions: Printf.failwithf and more. The Printf module now supports the failwithf function, which uses structured formatting to print to a string and then raise a Failure exception for this string. The new printer bsprintf is also supported: this prints to a string but intermediary functions print to string buffers. More general compositional forms of Printf operators are also included that let you specify a 'final action' for the printig such as flushing or raising an exception. Finally the OCaml-style 'format4' printer specifications are now also supported - these enable overall return types to be distinct from the types generated by intermediary printers.

Inclusion of a very preliminary release of a top-level command-line interactive environment for F#. The top-level environment will be fsi.exe. This is work in progress, and is included only for testing purposes.

Inclusion of a very preliminary release of FSharp.Compiler.dll, a hostable F# compiler. This is work in progress, and is included only for testing purposes.

Defining Events in F# Events should be defined using new definitions in Microsoft.FSharp.Idioms. For example:

open System.Windows.Forms
open Idioms

type MyCanvas = 
  class 
    inherit Form
    val redrawListeners: EventListeners
    member x.Redraw = x.redrawListeners.Event
    override x.OnPaint(args) = x.redrawListeners.Fire(args)

    new() = { inherit Form(); redrawListeners= new EventListeners() }
  end

let form = new MyCanvas()
do form.Redraw.Add(fun args -> Printf.printf "OnRedraw\n")
do form.Activate()
do Application.Run(form)

Note we are using a property of type Idioms.IEvent<PaintEventArgs> to represent the event. The object returned by this property has Add, AddHandler and RemoveHandler methods (see below). In a future release of the compiler properties of type Idioms.IEvent<PaintEventArgs> will automatically result in appropriate .NET metadata for the event being inserted in the generated assembly. In the current release events defined using this mechanism may still be used from C# and other .NET by using AddHandler and other methods on themediating object.

type Idioms.SimpleEventArgs<'a> = 
  class 
    inherit System.EventArgs 
    member Data: 'a 
    new: 'a -> SimpleEventArgs<'a>
  end

type Idioms.SimpleEventHandler<'a> =  System.EventHandler>

type Idioms.IEvent<'a> = 
   interface 
      inherit IDelegateEvent >
      // The inheritance gives:
      //    abstract AddHandler: SimpleEventHandler<'a> -> unit
      //    abstract RemoveHandler: SimpleEventHandler<'a> -> unit 

      // We add this one, which from F# code this is very simple to use:
      abstract Add: ('a -> unit) -> unit
   end

type Idioms.event<'a> = IEvent<'a>

type Idioms.EventListeners<'a> 
  with
    member Fire: 'a -> unit
    member Event: IEvent<'a>
    new: unit -> EventListeners<'a>
  end

Changes between v1.0.8.0 and v1.0.8.6

Renamed fslib10ng.dll to fslib10.dll, since there was a bug with using F# with Visual Studio 2003, and also the "ng" (non-generic) suffix was redundant and clumsy.

Stabilized string hash codes across .NET v1.1 and v2.0. That is, F#'s structural hash function no longer hashes strings by calling String.GetHashCode, since the hash codes returned were different between version 1.1 and 2.0.

Fixed a bug with the debug marks being attached for the entrypoint of executables.

A special function Pervasives.rethrow is now supported. This rethrows the exception for the current "try/with" block. However, it may only be used in catch blocks. Using it in a first class way or outside a catch block will result in a binary that cannot be verified. The correct use of this function is not checked in this version of F# but will be checked in a later version.

Fixed a bug that prevented the generic EventHandler type from being used (or indeed any generic type that was in the same namespace as a non-generic type with an identical name).

F# .EXEs that do not use function values, list types, option values or any other fslib or mllib no longer pick up a dependency on fslib.dll. DLLs incorporating interface data or optimization data still acquire a dependency.

Changes between v1.0.4.3 and v1.0.8.0

Welcome James Margetson to the F# team!

F# now works with Whidbey Beta 2 releases of .NET (EDITOR: the latest releases no longer support Beta 2). F# can continue to be used with .NET 1.0 and 1.1, but can no longer be used with Whidbey Beta 1. If you are still using Whidbey Beta 1 and don't want to upgrade to Whidbey Beta 2 then add --cli-version 1.1 to your compilation switches to compile for .NET 1.1 (likewise 1.0) instead.

Change to Library Naming. The F# libraries fslib and mllib now come in two flavours: one for use with .NET 1.x (no generics) and one for use with .NET 2.0 Beta 2 and beyond (this is to ensure that the library can take advanatage of new features of the platform). The .NET 1.x version of the library has the suffix "10" attached. Thus you will see both fslib.dll and fslib10.dll in this release. F# will automatically reference the correct DLL. When compiling C# code with .NET 1.x you will need to reference fslib10.dll and mllib10.dll.

Rename some internal functions. Some internal functions such as GenericCompare have been renamed appropriately, e.g. to StructuralCompare.

Performance improvements. Language additions. Compiler additions.

Bugs fixed

351	F# Compiler	Use of invalid format specifier such as %l in a Printf string gives a poor error message
381	F# Library	input_char cause exception to be thrown
318	F# Compiler	F# lets two constructors have the same name and gives error when emitting binary
321	F# Compiler	compiler error reported by Greg Lee
332	F# Compiler	F# reports error when a "for" variable is used within an inner closure, complaining it is mutable
333	F# Compiler	Cannot hide exception declarations
252	F# Perf		fsyacc parser is allocating a lot of list and option nodes
399	F# Perf		Move generation of comparison and hash methods earlier (to typechecker) so that the code can be fully optimized (and inlined!!)
281	Abstract IL	implement output of debug symbols for Abstract IL and bootstrapped compiler
175	F# Tools	Implement error recovery in fsyacc generated parsers

Changes between v1.0.4.0 and v1.0.4.3

Restricted operator overloading to built-in types only for the time being. This is simply an implementation incompleteness.

Added float32 and other float32-related operations to Pervasives.

Changes between v1.0.3.0 and v1.0.4.0

Constrained Type Parameters

F# now allows type parameters to be constrained to specify the minimum functionality the instantiating type must support.

You may be familiar with constrained type parameters from elsewhere. For example, C# and .NET generics support 'subtype' constraints on generic type variables. OCaml supports structural 'object-type' constraints and an additional kind of variable known as a 'row' variable. Standard ML supports a two minor forms of constrained polymorphism in the form of record types (which must be locally resolved) and equality types.

Constrained polymorphism affects both type checking and type inference. In this release, F# supports coercion constraints (on any type variables) and overloaded operator constraints (on pseudo type variables).

Coercion constraints are of the form typar :> type, and also arise from the constructs expr :> type and pattern :> type. For example: