F # (pronounced eff-sharpe ) is a multi - paradigm programming language from the .NET Framework family of languages that supports functional programming in addition to imperative ( procedural ) and object-oriented programming . The F # structure is very similar to the OCaml structure, with the only difference being that F # is implemented on top of the .NET libraries and runtime. The language was developed by Don Syme at Microsoft Research in Cambridge , and is currently being developed by Microsoft Developer Division. F # integrates quite closely with the Visual Studio development environment and is included in Visual Studio 2010/2012/2013/2015/2017 ; Compilers for Mac and Linux have also been developed [1] .
| F # | |
|---|---|
| Language class | multi-paradigm : functional , object-oriented , generalized , imperative programming |
| Appeared in | 2005 |
| Author | Microsoft research |
| Developer | and the |
| File extension | , , or |
| Release | 4.6 ( march 29, 2019 ) |
| Type system | strict |
| Influenced | Objective Caml , C # , Haskell |
| License | Apache Software License |
| OS | Cross-platform software ( .NET Framework , Mono ) |
| Site | fsharp.org |
Microsoft has integrated the F # development environment in Visual Studio 2010 and later.
On November 4, 2010, the code of the F # compiler and its main libraries were published under Apache License 2.0 [2] .
Content
Features
F # code is type safe , often more compact than similar C # code due to type inference . F # has strong typing; implicit type conversions are completely absent, which completely eliminates errors related to type conversion.
Features such as generalized programming and higher-order functions allow you to write abstract generalized algorithms that control parameterized data structures (for example, arrays , lists , graphs , trees ).
In many languages, most values are variables. For example, as a result of the execution of the following C ++ code, the value x will be stored in the variable x : 3:
int x = 2 ;
x ++ ;
In F #, in contrast, by default, all values are constants. F # allows variables, for which it is necessary to specifically mark values as mutable using the word mutable:
let x = 2 // immutable value
let mutable y = 2 // variable
x <- 3 // error
y <- 3 // Ok. y = 3
F # also has reference types and objects, which can also contain mutable values. However, most of the code is pure functions , which avoids many errors and simplifies debugging. In addition, parallelization of programs is simplified. With all this, code rarely becomes more complicated than similar code in an imperative language.
One of the main ideas of F # is to make sure that the available code and types in a functional programming language can be easily accessed from other .NET languages. F # programs are compiled into CLR assemblies (files with the extensions .exe and .dll), however, to run them, you need to install the runtime package in addition to the .NET Framework.
An interesting feature (and difference from OCaml ) is the control of the logical nesting of code constructions due to indentation in the form of an arbitrary number of spaces (and only spaces). Tabs for this purpose are not supported. This leads to ongoing discussions in the forums of experienced developers who are used to using tabs in other programming languages.
Compiler and interpreter
F # is a compiled programming language, using the Common Intermediate Language (CIL) as an intermediate language, as well as in programs written in C # or VB.NET .
Along with the F # compiler (fsc), there is also the F # interpreter (fsi), which executes the F # code interactively.
A distinctive feature of the F # compiler and the F # interpreter is the ability to perceive the code in two different ways - immediately (by default) and deferred (the programmer needs to explicitly indicate this in the source code). In the case of immediate interpretation, the expressions are calculated in advance at the time the program is launched for execution, regardless of whether they are called during program execution or not. In this case, the productivity of program execution is often reduced, and there is an uneconomical expenditure of system resources (for example, memory). In the case of a lazy interpretation of the code, expressions are evaluated only at the moment when they are directly accessed during the execution of the program. This eliminates the program from the above disadvantages, but reduces predictability in terms of volume and sequence of resource use (CPU time, memory, input / output devices, etc.) at various stages of program execution.
Examples
The F # syntax is based on mathematical notation, and programming is a bit like algebra , which makes F # look like Haskell . For example, when you define a new type, you can indicate that the variables of this type will be “ integers or strings ”. Here's what it looks like:
type myType = IntVal of int | StringVal of string
An important example of such types is Option, which contains either a value of some type or nothing.
type Option <a> = None | Some of a
It is a standard type of F # and is often used in situations where the result of some code (for example, a search in the data structure) is a value that may not be obtained.
The code is also a mathematical notation. The following construction is equivalent to f (x) = x + 1 in the algebra:
let f x = x + 1
F # works as follows: type “ f ” represents “ int -> int ”, that is, the function receives an integer at the input and outputs the integer.
F # allows you to access absolutely everything that is in FCL . The syntax for working with .NET libraries in this sense is as close as possible to the C # syntax. Language features are noticeable when using the full range of F # features. For example, the following code applies a function to list items:
let rec map func lst =
match lst with
| [] -> []
| head :: tail -> func head :: map func tail
let myList = [ 1 ; 3 ; 5 ]
let newList = map ( fun x -> x + 1 ) myList
In " newList " is now located " [2;4;6] ".
The analysis of the list in this function is carried out with the help of another powerful possibility of comparison with the sample . It allows you to specify patterns that match the corresponding occurrences of the match operator. The first sample “[]” means an empty list. The second is a list consisting of the first element and tail (which can be an arbitrary list, including an empty one). In the second sample, the value of the head is associated with the variable head, and the tail with the tail (names can be arbitrary). Thus, in addition to the main task, the sample also allows the decomposition of complex data structures. For example, in the case of the Option type, pattern matching looks like this:
match x with
| Some v -> printfn "Found value% d." v
| None -> printfn "Nothing found."
| None -> printfn "Hello"
The language supports generator expressions defined for sets { … } , lists [ … ] and arrays [| … |] [| … |] For example:
let test n = [ for i in 0 .. n do
if i % 2 = 0 then
yield i ]
The map function is one of the standard functions on lists contained in the List module. There are also functions for other data structures declared in the Array, Set, Option modules.
A useful tool is the pipe-forward operator (|>), which allows you to write chains of function calls in reverse order. As a result, the following code takes place (intermediate values are indicated in the comments):
[ 1 ; 2 ; 5 ]
|> List . map ((+) 1 ) // [2; 3; 6]
|> List . filter ( fun x -> x % 2 = 0 ) // [2; 6]
|> List . sum // 8
Using the |> operator eliminates the need for a large number of brackets, and also changes the visual perception of the code. And now this code reads like this: take a certain list, add 1 to each element, then leave only even elements, return their sum. That is, it describes the sequence of actions performed on the original object in the order in which it occurs on the computer.
The following is a small demonstration of how .NET features extend the power of F #. One example is window applications and event processing. Event processing means - some actions in the program occur only as a reaction to certain events - user actions, connecting devices, etc. The project can be created both in Visual Studio and in any text document, which is then fed to the F # compiler (fsc).
// open - connecting modules and namespaces for using contained in them
// values, classes, and other modules.
open System.Windows.Forms // - classes Form (window), Button (button), etc.
// Beep - sound signal
// Some more parameters are passed as beep arguments that we don’t use
let beep _ = System . Console Beep ()
// create a window with the program name window! you must call the display function word - for example Application.Run (window)!
// Visible - boolean whether the window is visible
// TopMost - whether the window is displayed in the foreground (the order of windows with the same value in the reverse call order)
// Text - window title text
let window = new Form ( Visible = true , TopMost = true , Text = "" ,
Top = 0 , Left = 0 , Height = 512 , Width = 768 )
window . WindowState <- FormWindowState . Normal // Normal (, Minimized, Maximized) window. Just for example, not included in the constructor
window . ClientSizeChanged . Add beep
window . Keydown . Add beep
window . KeyPress Add beep
window . KeyUp . Add beep
Application . Run window // display window
Factorial
The recursive function of calculating factorial in a native way:
let rec fac n =
if n < 2 then 1
else n * fac ( n - 1 )
Factorial calculation function using list convolution and curried multiplication operation:
let fac n = List . fold (*) 1 [ 1 .. n ]
The recursive function for calculating Fibonacci numbers using the pattern matching method:
let rec fib n a b =
match n with
| 0 -> a
| 1 -> b
| _ -> fib ( n - 1 ) b ( a + b )
Notes
See also
- F *
- Boo
- Nemerle
- C #
- Haskell
- Scala
- OCaml
- Comparison of programming languages
Links
- F # (English) - Microsoft F # Developer Center.
- Introduction to F #. Evgeny Lazin, Maxim Moiseev, David Sorokin, “The Practice of Functional Programming”, 2010, No. 5
- Introduction to F # - Interview with Don Syme.
- Discussion of Don Syme's book on F # in Russian “The Definitive Guide to F #”
- Three paradigms of F # - IT daily blog, news, magazine, technologies
- Try F # Tutorials - Introducing the F # Language. programming
Literature
- Chris Smith (Smith, Chris). Programming in F # = Programming F #. - O'Reilly, 2011 .-- 448 p. - ISBN 978-5-93286-199-8 .
- Dmitry Soshnikov. Functional programming in F #. - Moscow: DMK Press, 2011 .-- 192 p. - ISBN 978-5-94074-689-8 .
- Syme, Don; Granicz, Adam; Cisternino, Antonio. Expert F #. - Apress, 2007. (English)