Some work in progress for F# 1.0.1 (the second 1.0 preview release)

I thought I would mention some details of the features I've been working on for the next preview release of F# 1.0.  Firstly, the main thing: intellisense.  This has been a joy to implement: the code for the Visual Studio plugin can access the internal lexer, parser, type checker and type-checking data structures of the F# typechecker directly, and it seems that features such as the instantiation of .NET generics with inferred type parameters will drop out very easily as a result. One screen shot is shown here.

Other things that will be included in the 1.0.1 release are nested modules and extensions to object expressions. Objects created via object expressions can now support multiple interfaces, which will also make F# a CLS Extender language according to the official definition of such things. The syntax we've settled on is:

  { new  with  interface  with  ... interface  with  } 

e.g.

  { new Object() with Finalize() = cleanupFunction(false); interface IDisposable with Dispose() = cleanupFunction(true); } 

(Actually the correct "disposal pattern" is a little more complex than this, but that is another discussion, covered w.r.t. C# by MSDN.)

Nested modules roughly correspond to nested classes containing static members, and will be compiled that way. This was a feature I held off adding to the language for some time: I do not find that they act as a truly useful device for organising very large APIs - at least not as useful as the devices provided by .NET (an analysis of when and where the ML module system is truly useful in practice would be a topic for another occasion - .NET provides a good environment to asses this, since there are many API designs available to provide the basis for an assessment).   But, putting my concerns aside, nested modules are used from time to time in important existing ML code, including in some internal Microsoft projects, in order to approximate a "." syntax, and so are worth having if only to ease the porting of existing code.

An interesting issue for nested modules is the atomicity of dynamic initialization, i.e. how many top level bindings get run for a dynamically loaded component (e.g. F# code compiled as a DLL), and when do they get run? This is discussed for existing F# code in the advanced topics section of the manual. For nested modules, the atomicity of dynamic initialization will still be on the granularity of top-level modules (i.e files). That is, all the bindings in a top-level module are executed for side-effects if any values in the file are required by other code that is executing.

There's lots of other goodness coming in the 1.0.1 release: .NET literals in pattern matching, more modules in MLLib (Float32, UInt32, UInt64, Nativeint, UNativeint, Stream and more), more samples and better documentation.  I'll discuss some of these in future posts!