Oct 24

Release notes for F# 1.1.12.5

The F# 1.1.12.5 release has been posted. This is mostly a minor bug-fixing release, with the exception of the first point below. Here are the full release notes.

High Precedence Application. A long-standing problem with the F# syntax is that method applications followed by property/field lookups such as obj.Method1(args).Method2(args).Property1.field2 have had to be written with very non-intuitive parentheses, e.g. ((obj.Method1(args)).Method2(args)).Property1.field2.

To fix this, this release incorporates a minor change in the F# syntax (with and without the #light syntax option). In particular, applications id(args) now have higher precedence (i.e. bind more tightly) than the dot-notation. This only applies when no spaces or other whitespace separate the identifier and the arguments.

–no-tailcalls now binary-format neutral. In prior versions the –no-tailcalls option was a global setting, hence requiring the use of special libraries that had tailcalls removed. Systems such as Mono now correctly support the .tail IL annotation and so a global version of this option is no longer required. The option is still supported, but will only affect the code being generated in the assembly currently being compiled and will not result in the selection of different runtime libraries.

Some revisions to the Microsoft.FSharp.Reflection API. Some functions have been renamed or moved to an inner module. Old versions of the functions have been marked Deprecated with an error message indicating the new version to use.

Most samples rewritten using #light.

Revert change to operator overloading made in 1.1.12.2 release.

The change to operator overloading in 1.1.12.2 was incorrect, as it disallows the use of legitimate .NET overloads. The upshot is that the basic operators now have the following signatures. These indicate that the two argument types and the return type may indeed all be different, and knowledge of the return type and the second argument type are not sufficient to resolve the overloading - a type annotation may be required to give the precise type of the first argument.

val inline (+)  : ^a -> ^b -> ^c when ^a : (static member (+)    : ^a * ^b -> ^c)
val inline (-)  : ^a -> ^b -> ^c when ^a : (static member (-)    : ^a * ^b -> ^c)
val inline ( * ): ^a -> ^b -> ^c when ^a : (static member ( * )  : ^a * ^b -> ^c)
val inline (/)  : ^a -> ^b -> ^c when ^a : (static member (/)    : ^a * ^b -> ^c)
val inline (%)  : ^a -> ^b -> ^c when ^a : (static member (%)  : ^a * ^b -> ^c)
val inline (mod): ^a -> ^b -> ^c when ^a : (static member (%)  : ^a * ^b -> ^c)

We are considering a design revision which would allow more restricted specifications of permitted overloads, but are currently erring on the side of generality, even at the cost of occasional additional type annotations.

Bug fixes.

700        F# Language     undentation should be allowed when () and {} immediately follow an "="
702     F# Compiler     unbound type variable problems for inner constrained polymorphic definitions
                        fix bug with #load in F# Interactive (module paths reference incorrect version after reload)
                        Samples101 failed to compile
                        fix minor bug with #light not at start-of-file

Oct 24

ASP.NET web applications in F#

CodeDOM and providers

CodeDOM (Code Document Object Model) is set of objects (located in System.CodeDom namespace) that can be used for representing logical structure of .NET source code. For example you can use CodeTypeDeclaration class to represent class declaration or CodeAssignStatement to represent assignment in the body of method. CodeDom is language independent and CodeDOM structure can be translated to source code in specified language using code generator (class that implements ICodeGenerator namespace). The CodeDOM structure can be also compiled to assembly using code compiler (implementation of ICodeCompiler interface). Microsoft provides several code providers with .NET Framework (for C#, VB.Net, JScript and C++), but you can add your own by by implementing previously mentioned interfaces.

In the .NET Framework, CodeDOM is used for automatic code generation. For example when you add web reference to your project, the wrapper class that calls web service is generated using CodeDom. Some more examples are typed dataset (generated from XSD files) and generator for data layer in the upcoming LINQ project, but the most interesting use for CodeDOM for me is in ASP.NET 2.0.

Typical ASP.NET web page consists of several aspx/ascx files and associated code behind files written in one of the .NET languages. When building web page, ASP.NET uses CodeDOM for building aspx/ascx files. It parses these files and generates according CodeDOM structure. For example declaration is translated to declaration of btn member and code that assigns new instance of Button object to this member. This generated structure is compiled to .NET assemblies using code compiler and the web page is ready to use. If you use any in-line code in ASP.NET page, it is included in the CodeDOM structure as literal, which means that if the generated CodeDOM is compiled using C# code compiler, it can contain literals only in C# language (because you can’t mix languages in one source file).

ASP.NET and F#

In ASP.NET 1.1 you could compile code behind files using different compiler than the rest of the page (source generated from aspx/ascx). This method is used by ASP.NET in F# demo by Robert Pickering [1]. The more complex approach that is available in ASP.NET 2 is to write CodeDomProvider implementation for F#. This makes it possible to write F# in-line code in web pages and this method allows you to fully benefit of ASP.NET compilation model (for example you can use Publish Web Site command in Visual Studio).

FSharpCodeProvider & AspNetFsharpCodeProvider

I wanted to implement CodeDomProvider for the F# language, for the reasons mentioned above. Currently, I’m presenting version of provider that is able to compile ASP.NET pages quite well, however I implemented only features required by ASP.NET, so the provider is not complete. There are also some problems that has to be handled specially (for example, F# doesn’t support partial classes), so apart from standard provider (FsharpCodeProvider), I also implemented AspNetFsharpCodeProvider that contains several ‘hacks’ for ASP.NET.

How to use it?

Important: For correct functionality of F# CodeDOM compiler, you have to modify your system variable PATH to include ‘bin’ directory of your F# installation folder. This is because, code compiler uses fsc.exe for compilation and there is no simple way for finding where the F# is installed.

The most simple way to start creating ASP.NET web sites in F# is to use VS.NET project template that you can find in the downloads section. Using this template, you can create web page that is already configured to use F# language. After installation, select File - New - WebSite.. and in the dialog select language ‘Visual C#’ (it is not possible to add another language AFAIK) and than select ‘F# WebSite’ template.

If you want to configure ASP.NET web site to use F# code provider manually, you have to do the following steps. First modify the web.config file to include the following elements in the compilation section:


  
    
      
        
      
    
  

This adds reference to the assembly that contains the AspNetFShaprCodeProvider class and it configures ASP.NET to use F# code generator for aspx files which Language attribute is set to “F#”. When this is done, you can add F# page by adding aspx and code behind fs files. In the Page directive, set the Language attribute to “F#” and define the code behind class in the fs file.

The following example shows code behind class for simple web page (that contains one button with ID set to btnOk):

namespace FSharpWeb

open System;;
open System.Web.UI.WebControls;;

// Code behind class declaration
type Default = class inherit System.Web.UI.Page as base
  // Declaration of button control
  val mutable btnOk : Button;
  // All fields must be initialized in constructor
  new() = { btnOk = null; }
  // Set text of button in onload
  override this.OnLoad (e) =
    btnOk.Text 
              

There is still one little difference when compared with C#, which is that it is required to manually declare all controls (with ID) that are on the page (btnOk in this example). This is because F# doesn’t (currently) support partial classes and so the partial class with control declarations that is generated by ASP.NET is dropped by the CodeDOM provider. The rest is very similar to how you develop ASP.NET pages in other languages; you can see more examples if you download attached example application. More information regarding object oriented programming in F# can be found in F# manual available at F# homepage [3].

Other CodeDom provider notes

As I mentioned earlier, the CodeDOM generator I created is still very limited and it is tested only with ASP.NET. You can find list of not implemented features in the release notes (see downloads). In the future, I’d like to extend it to support generating code for accessing web services too (code is generated using wsdl tool). If you have any interesting idea, how it could be used or if you have any other comments, ideas, bug fixes, etc., please let me know (at [email protected]).

Downloads & links