Jun 26

The F# Programming Language Informal Specification

Leave a Reply

1. Introduction

F# is a scalable, script-like, type-safe, efficiently executing functional/imperative/object-oriented programming language. It aims to be the premier type-safe symbolic programming language for the .NET platform.

This manual describes the F# language through a mixture of informal and semi-formal techniques.

F# is similar to the Caml programming language family, and was partially inspired by it. See F# and OCaml for more details.

2. Lexical Specification

Comments. Comments are delimited by (* and *) and may be nested. In addition, C#/C++-style // single-line comments may be used and extend to the end of a line.

Strings embedded within comments are parsed without looking for closing *) marks, e.g., (* Here’s a code snippet: let s = “*)” *) is a valid comment.

Conditional Compilation. #if ident/#endif directives delimit conditional compilation sections. Text in a #if section is included in the compilation if the given ident is defined in the compilation environment, typically via the command line option –define. F# also allows code to be cross-compiled as both F# and OCaml code. Sections marked

         (*IF-FSHARP  ... ENDIF-FSHARP*)
     or  (*F#         ... F#*)

are included when compiling with the F# compiler, and text surrounded by

         (*IF-CAML*)  ...  (*ENDIF-CAML*)
      or (*IF-OCAML*)  ... (*ENDIF-OCAML*)

is excluded when compiling with the F# compiler. Of course the converse holds when compiling programs using an OCaml compiler.

Keywords. The keywords of the F# language are shown below.

abstract and as assert begin class default delegate do done downcast downto else end
enum exception extern false finally for fun function if in inherit interface land lazy let
match member  module mutable namespace new null of open or override rec sig static struct then to true try
type val when inline upcast while with void

The following identifiers are also keywords because they are keywords in OCaml. However their use is not recommended in F# code, since symbolic alternatives are available.

asr land lor lsl lsr lxor mod

The symbols act as keywords:

| -> ->> ] [| |] { } #

The following identifiers are used in OCaml and/or C# and are reserved for future use by F#. The –ml-compatibility option permits OCaml identifiers to be used.

async atomic break checked component const constraint
constructor continue decimal eager event
external fixed functor include method mixin object
process property protected public pure readonly return sealed
virtual volatile {}

Operators and Symbolic Keywords. Operator names are sequences of characters as shown below, except where a combination of characters is used as a symbol elsewhere in the language. Precedence is specified below.

    first-op-char := !$%&*+-./[email protected]^|~
    op-char       := first-op-char | :
    operator      := first-op-char op-char*

For example, &&& and ||| are valid operators. These have default definitions as overloaded bitwise manipulations on integer types.

Certain Unicode characters may also be included in the operator set. The final choice of such characters is as yet unspecified, though it may be specified in the change notices with each compiler release.

In addition, the following operators correspond to syntactic forms for expressions.

    .[]       (expression form "a.[i]")

The .[] forms have default definitions as overloaded lookup and assignment on arrays, dictionarys, maps and any value supporting an Item property. The .() forms have default definitions as array lookup. In theory the operators can be redefined, e.g., the example below shows how to do this for byte arrays, but this is rarely used in practice:

    let (.[])   s n   = Bytearray.get s n
    let (.[]

For compatibility with OCaml the following identifiers are parsed as infix operators, corresponding to logical bitwise manipulations:

    land lor lsl lsr lxor mod

However the corresponding overloaded symbolic operators (&&& etc.) are often preferred.

The following operators are assigned a meaning via lifted term quotation:

    quotation-operator-left :=
| op-char*