you have seen the basic structure of an f# program, so it will be easy to understand other basic building blocks of the f# programming language.
tokens in f#
an f# program consists of various tokens. a token could be a keyword, an identifier, a constant, a string literal, or a symbol. we can categorize f# tokens into two types −
- keywords
- symbol and operators
f# keywords
the following table shows the keywords and brief descriptions of the keywords. we will discuss the use of these keywords in subsequent chapters.
| keyword | description |
|---|---|
| abstract | indicates a method that either has no implementation in the type in which it is declared or that is virtual and has a default implementation. |
| and | used in mutually recursive bindings, in property declarations, and with multiple constraints on generic parameters. |
| as | used to give the current class object an object name. also used to give a name to a whole pattern within a pattern match. |
| assert | used to verify code during debugging. |
| base | used as the name of the base class object. |
| begin | in verbose syntax, indicates the start of a code block. |
| class | in verbose syntax, indicates the start of a class definition. |
| default | indicates an implementation of an abstract method; used together with an abstract method declaration to create a virtual method. |
| delegate | used to declare a delegate. |
| do | used in looping constructs or to execute imperative code. |
| done | in verbose syntax, indicates the end of a block of code in a looping expression. |
| downcast | used to convert to a type that is lower in the inheritance chain. |
| downto | in a for expression, used when counting in reverse. |
| elif | used in conditional branching. a short form of else if. |
| else | used in conditional branching. |
| end |
in type definitions and type extensions, indicates the end of a section of member definitions. in verbose syntax, used to specify the end of a code block that starts with the begin keyword. |
| exception | used to declare an exception type. |
| extern | indicates that a declared program element is defined in another binary or assembly. |
| false | used as a boolean literal. |
| finally | used together with try to introduce a block of code that executes regardless of whether an exception occurs. |
| for | used in looping constructs. |
| fun | used in lambda expressions, also known as anonymous functions. |
| function | used as a shorter alternative to the fun keyword and a match expression in a lambda expression that has pattern matching on a single argument. |
| global | used to reference the top-level .net namespace. |
| if | used in conditional branching constructs. |
| in | used for sequence expressions and, in verbose syntax, to separate expressions from bindings. |
| inherit | used to specify a base class or base interface. |
| inline | used to indicate a function that should be integrated directly into the caller's code. |
| interface | used to declare and implement interfaces. |
| internal | used to specify that a member is visible inside an assembly but not outside it. |
| lazy | used to specify a computation that is to be performed only when a result is needed. |
| let | used to associate, or bind, a name to a value or function. |
| let! | used in asynchronous workflows to bind a name to the result of an asynchronous computation, or, in other computation expressions, used to bind a name to a result, which is of the computation type. |
| match | used to branch by comparing a value to a pattern. |
| member | used to declare a property or method in an object type. |
| module | used to associate a name with a group of related types, values, and functions, to logically separate it from other code. |
| mutable | used to declare a variable, that is, a value that can be changed. |
| namespace | used to associate a name with a group of related types and modules, to logically separate it from other code. |
| new |
used to declare, define, or invoke a constructor that creates or that can create an object. also used in generic parameter constraints to indicate that a type must have a certain constructor. |
| not | not actually a keyword. however, not struct in combination is used as a generic parameter constraint. |
| null |
indicates the absence of an object. also used in generic parameter constraints. |
| of | used in discriminated unions to indicate the type of categories of values, and in delegate and exception declarations. |
| open | used to make the contents of a namespace or module available without qualification. |
| or |
used with boolean conditions as a boolean or operator. equivalent to ||. also used in member constraints. |
| override | used to implement a version of an abstract or virtual method that differs from the base version. |
| private | restricts access to a member to code in the same type or module. |
| public | allows access to a member from outside the type. |
| rec | used to indicate that a function is recursive. |
| return | used to indicate a value to provide as the result of a computation expression. |
| return! | used to indicate a computation expression that, when evaluated, provides the result of the containing computation expression. |
| select | used in query expressions to specify what fields or columns to extract. note that this is a contextual keyword, which means that it is not actually a reserved word and it only acts like a keyword in appropriate context. |
| static | used to indicate a method or property that can be called without an instance of a type, or a value member that is shared among all instances of a type. |
| struct |
used to declare a structure type. also used in generic parameter constraints. used for ocaml compatibility in module definitions. |
| then |
used in conditional expressions. also used to perform side effects after object construction. |
| to | used in for loops to indicate a range. |
| true | used as a boolean literal. |
| try | used to introduce a block of code that might generate an exception. used together with with or finally. |
| type | used to declare a class, record, structure, discriminated union, enumeration type, unit of measure, or type abbreviation. |
| upcast | used to convert to a type that is higher in the inheritance chain. |
| use | used instead of let for values that require dispose to be called to free resources. |
| use! | used instead of let! in asynchronous workflows and other computation expressions for values that require dispose to be called to free resources. |
| val | used in a signature to indicate a value, or in a type to declare a member, in limited situations. |
| void | indicates the .net void type. used when interoperating with other .net languages. |
| when | used for boolean conditions (when guards) on pattern matches and to introduce a constraint clause for a generic type parameter. |
| while | introduces a looping construct. |
| with | used together with the match keyword in pattern matching expressions. also used in object expressions, record copying expressions, and type extensions to introduce member definitions, and to introduce exception handlers. |
| yield | used in a sequence expression to produce a value for a sequence. |
| yield! | used in a computation expression to append the result of a given computation expression to a collection of results for the containing computation expression. |
some reserved keywords came from the ocaml language −
| asr | land | lor | lsl | lsr | lxor | mod | sig |
some other reserved keywords are kept for future expansion of f#.
| atomic | break | checked | component | const | constraint | constructor |
| continue | eager | event | external | fixed | functor | include |
| method | mixin | object | parallel | process | protected | pure |
| sealed | tailcall | trait | virtual | volatile |
comments in f#
f# provides two types of comments −
- one line comment starts with // symbol.
- multi line comment starts with (* and ends with *).
a basic program and application entry point in f#
generally, you don’t have any explicit entry point for f# programs. when you compile an f# application, the last file provided to the compiler becomes the entry point and all top level statements in that file are executed from top to bottom.
a well-written program should have a single top-level statement that would call the main loop of the program.
a very minimalistic f# program that would display ‘hello world’ on the screen −
(* this is a comment *) (* sample hello world program using f# *) printfn "hello world!"
when you compile and execute the program, it yields the following output −
hello world!