F Sharp (programming language)

F Sharp (programming language)
F#
Paradigm(s) multi-paradigm: functional, imperative, object-oriented
Appeared in 2002 (2002)
Designed by Microsoft Research
Developer Microsoft Developer Division
Stable release 2.0 (April 12, 2010 (2010-04-12))
Typing discipline static, strong, inferred
Influenced by Objective Caml, ML, C#, Haskell[1]
OS Cross-platform (.NET Framework, Mono)
License Apache license
Website Microsoft F# Developer Center
Wikibooks logo F Sharp Programming at Wikibooks

F# (pronounced F Sharp) is a multi-paradigm programming language, targeting the .NET Framework, that encompasses functional programming as well as imperative and object-oriented programming disciplines. It is a variant of ML and is largely compatible with the OCaml implementation. F# was initially developed by Don Syme at Microsoft Research but is now being developed at Microsoft Developer Division and is being distributed as a fully supported language in the .NET Framework and Visual Studio as part of Visual Studio 2010.[2]

Contents

Overview

F# is a strongly typed language that uses type inference. As a result, data types do not need to be explicitly declared by the programmer; they will be deduced by the compiler during compilation. However, F# also allows explicit data type declaration. Being a CLI compliant language, F# supports all CLI types and objects but it extends the type system and categorizes types as immutable types or mutable types. CLI objects classify as mutable types (which can be edited in-place), and are used to provide an object-oriented programming model. Immutable types (editing such a type creates a new instance without overwriting the older one) are primarily used for functional programming.

Like ML, F# includes a functional programming component supporting eager evaluation. For functional programming, it provides several constructs and a set of immutable types: tuples, records, discriminated unions and lists.[3]

An n-tuple represents a collection of n values, where n ≥ 0. The value n is called the arity of the tuple. The type unit corresponds to the 0-tuple and it has one value only: (), which conveys no information. The type unit is used to implement functions that need no input and/or return no value. A 3-tuple would be represented as (A, B, C), where A, B and C are values of possibly different types. A tuple can be used only to store values when the number of values is known at design-time and stays constant throughout execution.

A record is a specialization of tuple where the data members are named, as in { Name:string; Age:int }. Records can be created as { Name="AB"; Age=42 }. The with keyword is used to create a copy of a record, as in { r with Name="CD" }, which creates a new record by copying r and changing the value of the Name field (assuming the record created in the last example was named r).

The list type is a regular linked list represented either using a head::tail notation (:: is the cons operator) or a shorthand as [item1; item2; item3]. An empty list is written [].

The other sort of algebraic data type mentioned, "discriminated unions" (type-safe versions of C unions), can be defined to hold a value of any of a pre-defined type. For example,

 type A = 
    | ConstructorX of string
    | ConstructorY of int

can hold values as instantiated by either constructor. The type of the values the constructors will act on can be defined as well.

Constructors are used to create a view of the data type different from the actual implementation, as required for supporting the Active Patterns concept.[3] Data types are created with the type keyword. F# uses the let keyword for binding type values to a name (variable).[3]

F# uses pattern matching to resolve names into values. It is also used when accessing discriminated unions. Functions using a discriminated union provide different expressions to be invoked, associated with the data type in the union. The union is matched against these data types, and the expression associated with the match is invoked. F# also supports the Active Patterns pattern. It is used, for example, when a type needs to provide multiple views. For example, an exponential number will provide both the final value, as well as the base and exponents.[3]

All functions in F# are instances of the function type, and are immutable as well.[3] Functions can be curried. Being an instance of a type, functions can be passed as arguments to other functions, resulting in higher order functions. F# supports lambda functions and closures as well.[3] Like other functional programming languages, F# allows function composition using the >> operator. Every statement in F#, including if statements and loops, is a composable expression with a definite return type as well.[3] Functions and expressions that do not return any value have a return type of unit.

The F# extended type system is implemented as generic .NET types. The Record type creates a .NET class with the field names as properties. Tuples are generic classes of type Tuple<_,_>. The number of type parameters define the number and types of the elements in the tuple. Discriminated unions are implemented as tagged unions. Functions are of type FastFunc<_,_> with type parameters specifying the parameter and return types.[4]

F#, like other .NET languages, can use .NET types and objects, using an imperative object-oriented style of programming. For imperative programming, F# supports for and while loops, arrays (created with the [| ... |] syntax, and number sequences written in shorthand as in 1 .. 25) and support for creating Object types (equivalent to .NET classes).[3] F# also allows extending the syntax to support embedding custom domain-specific languages within the F# language itself.[3]

F# provides sequence expressions[5] that allows for a defining a sequence block (seq { ... } or [ ... ] or [| ... |]) encapsulating constructs (either functions, conditional expressions or loops) that act on a collection and another function (or lambda), such that the function is invoked on the results yielded from the collection collection-processing expressions. For example, seq { for b in 0 .. 25 do if b < 15 then yield b*b } is a sequence expression that forms a sequence of squares of numbers from 0 to 14 by filtering out numbers from the range of numbers from 0 to 25. The sequence is lazily evaluated, i. e., the collection is processed and results yielded on-demand. It can be used for filtering and is the basis of support for LINQ queries. Sequence expressions are generalized as Computation Expressions which are equivalent to monads.[5]

Sequence expressions and computation expressions are also used for creating asynchronous workflows.[6] An asynchronous workflow is defined as a sequence of commands inside a async{ ... }, as in

 let asynctask = async
 {
     let req = WebRequest.Create(url)
     let! response = req.GetResponseAsync()
     use stream = response.GetResponseStream()
     use streamreader = new System.IO.StreamReader(stream)
     return streamreader.ReadToEnd()
 }

The let! allows the rest of the async block to be defined as the delegate and passed as the callback function of an asynchronous operation. This helps deal with inversion of control issues.[6] The async block is invoked using the Async.Run function. Multiple async blocks are executed in parallel using the Async.Parallel function that takes a list of async objects (in the example, asynctask is an async object) and creates another async object to run the tasks in the lists in parallel. The resultant object is invoked using Async.Run.[6]

F# comes with a Microsoft Visual Studio language service that integrates it with the IDE. With the language service installed, Visual Studio can be used to create F# projects and the Visual Studio debugger used to debug F# code. In addition, it comes with a Visual Studio-hosted interactive console that executes F# code as it is being written.

SharpDevelop supports F# as well since version 3.0.

LinqPad supports F# as well since version 2.x.

Examples

A few small samples follow:

(* This is a comment *)
(* Sample hello world program *)
printfn "Hello World!"

A simple example that is often used to demonstrate the syntax of functional languages is the factorial function for non-negative 32-bit integers, here shown in F#:

let rec factorial n =
    match n with
    | 0 -> 1
    | _ -> n * factorial (n - 1)

Recursive function examples:

(* Print a list of numbers recursively *)
let rec printList lst =
    match lst with 
    | [] -> ()
    | h :: t -> 
        printf "%d\n" h
        printList t
 
(* Same thing, using matching against list elements *)
let rec printList2 l =
    match l with
    | []     -> ()
    | h :: t -> printfn "%A" h
                printList2 t
 
(* Using shorthand for match *)
let rec printList3 = function
    | []     -> ()
    | h :: t -> printfn "%A" h
                printList3 t
 
(* Or, using a higher-order function *)
let printlist4 lst = List.iter (printfn "%A") lst
(* Fibonacci Number formula *)
let rec fib n =
    match n with
    | 0 | 1 -> n
    | _ -> fib (n - 1) + fib (n - 2)
 
(* An alternative approach - a lazy recursive sequence of Fibonacci numbers *)
let rec fibs = Seq.cache <| seq { yield! [1; 1]                                  
                                  for x, y in Seq.zip fibs <| Seq.skip 1 fibs -> x + y }
 
(* Another approach - a lazy infinite sequence of Fibonacci numbers *)
let fibSeq = Seq.unfold (fun (a,b) -> Some(a+b, (b, a+b))) (1,1)
 
(* Print even fibs *)
[1 .. 10]
|> List.map     fib
|> List.filter  (fun n -> (n % 2) = 0)
|> printlist
 
(* Same thing, using sequence expressions *)
[ for i in 1..10 do
    let r = fib i
    if r % 2 = 0 then yield r ]
|> printlist
(* Sample Windows Forms Program *)
 
(* We need to open the System library for the STAThreadAttribute class *)
open System
 
(* We need to open the Windows Forms library *)
open System.Windows.Forms
 
(* Create a window and set a few properties *)
let form = new Form(Visible=true, TopMost=true, Text="Welcome to F#")
 
(* Create a label to show some text in the form *)
let label =
    let temp = new Label()
    let x = 3 + (4 * 5)
    (* Set the value of the Text*)
    temp.Text <- sprintf "x = %d" x
    (* Remember to return a value! *)
    temp
 
(* Add the label to the form *)
form.Controls.Add(label)
 
(* Finally, run the form  *)
[<STAThread>]
Application.Run(form)
(* Async workflows sample (parallel CPU and I/O tasks) *)
 
(* A very naive prime number detector *)
let isPrime (n:int) =
   let bound = int (System.Math.Sqrt(float n))
   seq {2 .. bound} |> Seq.exists (fun x -> n % x = 0) |> not
 
(* We are using async workflows *)
let primeAsync n =
    async { return (n, isPrime n) }
 
(* Return primes between m and n using multiple threads *)  
let primes m n =
    seq {m .. n}
        |> Seq.map primeAsync
        |> Async.Parallel
        |> Async.RunSynchronously
        |> Array.filter snd
        |> Array.map fst
 
(* Run a test *)
primes 1000000 1002000
    |> Array.iter (printfn "%d")

See also

Notes

References

  • Syme, Don; Granicz, Adam; Cisternino, Antonio (2007). Expert F#. Apress 
  • Harrop, Jon (2010). Visual F# 2010 for Technical Computing. Flying Frog Consultancy 
  • Pickering, Robert (2007). Foundations of F#. Apress 
  • Smith, Chris (2009). Programming F#. O'Reilly 
  • Petricek, Tomas (2009). Real World Functional Programming With Examples in F# and C#. Manning Publications 

External links


Wikimedia Foundation. 2010.

Игры ⚽ Нужно решить контрольную?

Look at other dictionaries:

  • C Sharp (programming language) — The correct title of this article is C# (programming language). The substitution or omission of the # sign is because of technical restrictions. C# Paradigm(s) multi paradigm: structured, imperative …   Wikipedia

  • A Sharp (programming language) — A Sharp may refer to multiple computer programming languages:*A Sharp (.NET), a port of the Ada programming language to the .NET environment *A Sharp (Axiom), a programming language for the Axiom computer algebra system …   Wikipedia

  • APL (programming language) — APL Paradigm(s) array, functional, structured, modular Appeared in 1964 Designed by Kenneth E. Iverson Developer Kenneth E. Iverson …   Wikipedia

  • Criticism of the APL programming language — The APL programming language has been used since the mid 1960s on mainframe computers and has itself evolved in step with computers and the computing market. APL is not widely used, but minimalistic and high level by design, at several points in… …   Wikipedia

  • Pascal (programming language) — Pascal Paradigm(s) imperative, structured Appeared in 1970 Designed by Niklaus Wirth Typing discipline static, strong, safe …   Wikipedia

  • Oxygene (programming language) — Oxygene Developer RemObjects Software Stable release 3.0.21 (August 29, 2009; 2 years ago (2009 08 29)) Influenced by Object Pas …   Wikipedia

  • Java (programming language) — infobox programming language name = Java paradigm = Object oriented, structured, imperative year = 1995 designer = Sun Microsystems latest release version = Java Standard Edition 6 (1.6.0) latest release date = latest test version = latest test… …   Wikipedia

  • Euclid (programming language) — Euclid is an imperative programming language for writing verifiable programs. It was designed by Butler Lampson and associates at the Xerox PARC lab in the mid 1970s. The implementation was led by Ric Holt at the University of Toronto and James… …   Wikipedia

  • K (programming language) — Infobox programming language name = K logo = paradigm = array, functional year = 1993 designer = Arthur Whitney developer = Kx Systems latest release version = latest release date = typing = dynamic, strong implementations = dialects = influenced …   Wikipedia

  • A Programming Language — APL, abgekürzt für A Programming Language, ist eine üblicherweise interpretierte Programmiersprache. Sie wurde von Kenneth E. Iverson und seinen Kollegen bei IBM in der 1960er Jahren als algorithmische Notation entwickelt. Einige Jahre später… …   Deutsch Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”