F Sharp (linguagem de programação) - F Sharp (programming language)
Paradigma | Multi-paradigma : funcional , imperativo , orientado a objetos , metaprogramação , reflexivo , concorrente |
---|---|
Família | ML |
Projetado por | Don Syme , Microsoft Research |
Desenvolvedor | Microsoft , The F # Software Foundation |
Apareceu pela primeira vez | 2005 | , versão 1.0
Versão estável | |
Versão de visualização | Versão 5.0 / 2 de abril de 2019
|
Disciplina de digitação | Estático , forte , inferido |
SO | Plataforma cruzada : .NET , .NET Framework , Mono |
Licença | Licença MIT |
Extensões de nome de arquivo | .fs, .fsi, .fsx, .fsscript |
Local na rede Internet | fsharp |
Influenciado por | |
C # , Erlang , Haskell , ML , OCaml , Python , Scala | |
Influenciado | |
C # , Elm , F * , LiveScript | |
|
F # (pronuncia-se F sustenido ) é uma linguagem de programação funcional , de propósito geral, fortemente tipada e multiparadigma , que abrange métodos de programação funcionais , imperativos e orientados a objetos . F # é mais frequentemente usado como uma linguagem de plataforma cruzada Common Language Infrastructure (CLI) no .NET , mas também pode gerar JavaScript e código de unidade de processamento gráfico (GPU).
F # é desenvolvido pela F # Software Foundation , Microsoft e colaboradores abertos. Um compilador de plataforma cruzada de código aberto para F # está disponível na F # Software Foundation. F # é uma linguagem com suporte total no Visual Studio e JetBrains Rider . Plug-ins que suportam F # existem para muitos editores amplamente usados, mais notavelmente a extensão Ionide para Visual Studio Code e integrações para outros editores, como Vim e Emacs .
F # é um membro da família de linguagens ML e se originou como uma implementação do .NET Framework de um núcleo da linguagem de programação OCaml . Também foi influenciado por C # , Python , Haskell , Scala e Erlang .
História
Versões
No decorrer de seu desenvolvimento, a linguagem passou por várias versões:
Versão | Especificação de linguagem | Encontro | Plataformas | Tempo de execução |
---|---|---|---|---|
F # 1.x | Maio de 2005 | janelas | .NET 1.0 - 3.5 | |
F # 2.0 | Agosto de 2010 | Abril de 2010 | Linux , macOS , Windows | .NET 2.0 - 4.0, Mono |
F # 3.0 | Novembro de 2012 | Agosto de 2012 |
Linux , macOS , Windows ; JavaScript , GPU |
.NET 2.0 - 4.5, Mono |
F # 3.1 | novembro de 2013 | outubro 2013 |
Linux , macOS , Windows ; JavaScript , GPU |
.NET 2.0 - 4.5, Mono |
F # 4.0 | Janeiro de 2016 | Julho de 2015 | ||
F # 4.1 | Maio de 2018 | Março de 2017 | Linux , macOS , Windows , | .NET 3.5 - 4.6.2, .NET Core , Mono |
F # 4.5 | Agosto de 2018 | Linux , macOS , Windows , | .NET 4.5 - 4.7.2, .NET Core SDK 2.1.400 | |
F # 4.6 | Março de 2019 | Linux , macOS , Windows , | .NET 4.5 - 4.7.2, .NET Core SDK 2.2.300 | |
F # 4.7 | Setembro de 2019 | Linux , macOS , Windows , | .NET 4.5 - 4.8, .NET Core SDK 3.0.100 | |
F # 5.0 | Novembro de 2020 | Linux , macOS , Windows , | .NET SDK 5.0.100 |
Evolução da linguagem
F # usa um processo aberto de desenvolvimento e engenharia. O processo de evolução da linguagem é gerenciado por Don Syme da Microsoft Research como o ditador benevolente para a vida (BDFL) para o design da linguagem, juntamente com a F # Software Foundation. As versões anteriores da linguagem F # foram projetadas pela Microsoft e pela Microsoft Research usando um processo de desenvolvimento fechado.
F # é originário da Microsoft Research , Cambridge, Reino Unido. A linguagem foi originalmente desenhada e implementada por Don Syme , de acordo com quem na equipe fsharp, eles dizem que o F é para "Diversão". Andrew Kennedy contribuiu para o design de unidades de medida . As Ferramentas Visual F # para Visual Studio são desenvolvidas pela Microsoft. A F # Software Foundation desenvolveu o compilador e as ferramentas de código aberto F #, incorporando a implementação do compilador de código aberto fornecida pela equipe do Microsoft Visual F # Tools.
Recursos adicionados | |
---|---|
F # 1.0 |
|
F # 2.0 |
|
F # 3.0 |
|
F # 3.1 |
|
F # 4.0 |
|
F # 4.1 |
|
F # 4.5 |
|
F # 4.7 |
|
F # 5.0 |
|
Visão geral da linguagem
Programação funcional
F # é uma linguagem de programação funcional. Isso significa que em F # as funções são enfatizadas mais do que objetos e estruturas e outras construções de programação tradicionais. F # é uma linguagem funcional de tipagem forte que usa inferência de tipo . F # também permite anotações de tipo explícitas e as requer em algumas situações.
F # é uma linguagem baseada em expressão que usa avaliação rápida e também, em alguns casos, avaliação preguiçosa . Cada instrução em F #, incluindo if
expressões, try
expressões e loops, é uma expressão combinável com um tipo estático. Funções e expressões que não retornam nenhum valor têm um tipo de retorno de unit
. F # usa a let
palavra - chave para vincular valores a um nome. Por exemplo:
let x = 3 + 4
vincula o valor 7
ao nome x
.
Novos tipos são definidos usando a type
palavra - chave. Para programação funcional, F # fornece tupla , registro , união discriminada , lista , opção e tipos de resultado . Uma tupla representa um conjunto de n valores, onde n ≥ 0. O valor n é chamado de aridade da tupla. Uma tupla de 3 seria representada como (A, B, C)
, onde A, B e C são valores de tipos possivelmente diferentes. Uma tupla pode ser usada para armazenar valores apenas quando o número de valores é conhecido em tempo de design e permanece constante durante a execução.
Um registro é um tipo onde os membros de dados são nomeados. Aqui está um exemplo de definição de registro:
type R =
{ Name : string
Age : int }
Os registros podem ser criados como . A palavra-chave é usada para criar uma cópia de um registro, como em , que cria um novo registro copiando e alterando o valor do campo (assumindo que o registro criado no último exemplo foi nomeado ).
let r = { Name="AB"; Age=42 }
with
{ r with Name="CD" }
r
Name
r
Uma união discriminada tipo é um tipo seguro versão do sindicatos C . Por exemplo,
type A =
| UnionCaseX of string
| UnionCaseY of int
Os valores do tipo de união podem corresponder a qualquer caso de união. Os tipos de valores transportados por cada caso de união estão incluídos na definição de cada caso.
O tipo de lista é uma lista vinculada imutável representada por uma notação ( é o operador contras ) ou uma abreviatura como . Uma lista vazia é escrita . O tipo de opção é um tipo de união discriminado com opções ou . Os tipos F # podem ser genéricos , implementados como tipos .NET genéricos.
head::tail
::
[item1; item2; item3]
[]
Some(x)
None
F # oferece suporte a funções lambda e encerramentos . Todas as funções em F # são valores de primeira classe e são imutáveis. As funções podem ser curry . Sendo valores de primeira classe, as funções podem ser passadas como argumentos para outras funções. Como outras linguagens de programação funcional, F # permite a composição de funções (ciência da computação) usando os operadores >>
e <<
.
F # fornece
expressões de sequência que definem uma sequênciaseq { ... }
, lista[ ... ]
ou array[| ... |]
por meio de código que gera valores. Por exemplo,
seq { for b in 0 .. 25 do
if b < 15 then
yield b*b }
forma uma sequência de quadrados de números de 0 a 14, filtrando os números do intervalo de números de 0 a 25. As sequências são geradores - os valores são gerados sob demanda (ou seja, são avaliados lentamente ) - enquanto as listas e matrizes são avaliadas avidamente .
F # usa correspondência de padrões para vincular valores a nomes. A correspondência de padrões também é usada ao acessar uniões discriminadas - a união é o valor correspondido com as regras de padrão e uma regra é selecionada quando uma correspondência é bem-sucedida. F # também oferece suporte a padrões ativos como uma forma de correspondência de padrões extensível. É usado, por exemplo, quando existem várias maneiras de correspondência em um tipo.
F # suporta uma sintaxe geral para definir cálculos composicionais chamados expressões de computação . Expressões de sequência, cálculos assíncronos e consultas são tipos particulares de expressões de computação. Expressões de computação são uma implementação dopadrãomonad.
Programação imperativa
O suporte F # para programação imperativa inclui
-
for
rotações -
while
rotações -
arrays , criados com a
[| ... |]
sintaxe -
tabela hash , criada com a
dict [ ... ]
sintaxe ouSystem.Collections.Generic.Dictionary<_,_>
tipo.
Valores e campos de registro também podem ser rotulados como mutable
. Por exemplo:
// Define 'x' with initial value '1'
let mutable x = 1
// Change the value of 'x' to '3'
x <- 3
Além disso, o F # oferece suporte ao acesso a todos os tipos e objetos CLI, como aqueles definidos no System.Collections.Generic
namespace que define estruturas de dados imperativas.
Programação orientada a objetos
Como outras linguagens CLI ( Common Language Infrastructure ), o F # pode usar tipos CLI por meio da programação orientada a objetos. O suporte F # para programação orientada a objetos em expressões inclui:
- Notação de ponto, por exemplo,
x.Name
- Expressões de objeto, por exemplo,
{ new obj() with member x.ToString() = "hello" }
- Construção de objetos, por exemplo,
new Form()
- Testes de tipo, por exemplo,
x :? string
- Coações de tipo, por exemplo,
x :?> string
- Argumentos nomeados, por exemplo,
x.Method(someArgument=1)
- Setters nomeados, por exemplo,
new Form(Text="Hello")
- Argumentos opcionais, por exemplo,
x.Method(OptionalArgument=1)
O suporte para programação orientada a objetos em padrões inclui
- Testes de tipo, por exemplo,
:? string as s
- Padrões ativos, que podem ser definidos sobre os tipos de objeto
As definições de tipo de objeto F # podem ser definições de tipo de classe, estrutura, interface, enum ou delegado, correspondendo aos formulários de definição encontrados em C # . Por exemplo, aqui está uma classe com um construtor tomando um nome e idade e declarando duas propriedades.
/// A simple object type definition
type Person(name : string, age : int) =
member x.Name = name
member x.Age = age
Programação assíncrona
F # oferece suporte à programação assíncrona por meio de fluxos de trabalho assíncronos . Um fluxo de trabalho assíncrono é definido como uma sequência de comandos dentro de um async{ ... }
, como em
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() }
O let!
indica que a expressão à direita (obtendo a resposta) deve ser feita de forma assíncrona, mas o fluxo só deve continuar quando o resultado estiver disponível. Em outras palavras, do ponto de vista do bloco de código, é como se obter a resposta fosse uma chamada de bloqueio, enquanto do ponto de vista do sistema, a thread não será bloqueada e poderá ser utilizada para processar outros fluxos enquanto o resultado necessário para este não se torna disponível.
O bloco assíncrono pode ser chamado usando a Async.RunSynchronously
função. Vários blocos assíncronos podem ser executados em paralelo usando a Async.Parallel
função que pega uma lista de async
objetos (no exemplo, asynctask
é um objeto assíncrono) e cria outro objeto assíncrono para executar as tarefas nas listas em paralelo. O objeto resultante é invocado usando Async.RunSynchronously
.
A inversão de controle em F # segue esse padrão.
Programação paralela
Programação paralela é suportado, em parte, através do Async.Parallel
, Async.Start
e outras operações que são executados blocos assíncronas em paralelo.
A programação paralela também é suportada por meio de Array.Parallel
operadores de programação funcional na biblioteca padrão F #, uso direto do System.Threading.Tasks
modelo de programação de tarefas, uso direto de pool de threads .NET e threads .NET e por meio da tradução dinâmica de código F # para mecanismos de execução paralela alternativos, como Código GPU .
Unidades de medida
O sistema do tipo F # oferece suporte à verificação de unidades de medida para números. O recurso de unidades de medida se integra com a inferência de tipo F # para exigir anotações de tipo mínimas no código do usuário.
Metaprogramação
F # permite algumas formas de personalização de sintaxe por meio de metaprogramação para oferecer suporte à incorporação de linguagens específicas de domínio personalizadas na linguagem F #, particularmente por meio de expressões de computação.
F # inclui um recurso para metaprogramação em tempo de execução chamado cotações. Uma expressão de aspas é avaliada como uma representação de árvore de sintaxe abstrata das expressões F #. Da mesma forma, as definições marcadas com o [<ReflectedDefinition>]
atributo também podem ser acessadas em seu formulário de cotação. As citações F # são usadas para vários fins, incluindo compilar o código F # em código JavaScript e GPU . (As cotações representam suas expressões de código F # como dados para uso por outras partes do programa, ao mesmo tempo em que exigem que o código F # seja sintaticamente correto).
Programação rica em informações
O F # 3.0 introduziu uma forma de metaprogramação em tempo de compilação por meio da geração de tipo estaticamente extensível, chamada de provedores de tipo F #. Os provedores de tipo F # permitem que o compilador F # e as ferramentas sejam estendidos com componentes que fornecem informações de tipo para o compilador sob demanda em tempo de compilação. Os provedores do tipo F # têm sido usados para fornecer acesso fortemente tipado a fontes de informação conectadas de uma forma escalonável, incluindo o gráfico de conhecimento do Freebase .
No F # 3.0, os recursos de cotação e expressão de cálculo do F # são combinados para implementar consultas LINQ . Por exemplo:
// Use the OData type provider to create types that can be used to access the Northwind database.
open Microsoft.FSharp.Data.TypeProviders
type Northwind = ODataService<"http://services.odata.org/Northwind/Northwind.svc">
let db = Northwind.GetDataContext()
// A query expression.
let query1 = query { for customer in db.Customers do
select customer }
A combinação de provedores de tipo, consultas e programação funcional fortemente tipada é conhecida como programação rica em informações .
Programação de agente
F # oferece suporte a uma variação do modelo de programação de Ator por meio da implementação na memória de agentes assíncronos leves. Por exemplo, o código a seguir define um agente e posta 2 mensagens:
let counter =
MailboxProcessor.Start(fun inbox ->
let rec loop n =
async { do printfn "n = %d, waiting..." n
let! msg = inbox.Receive()
return! loop(n+msg) }
loop 0)
Ferramentas de desenvolvimento
- O Visual Studio , com as ferramentas Visual F # da Microsoft instaladas, pode ser usado para criar, executar e depurar projetos F #. As ferramentas do Visual F # incluem um console interativo de loop de leitura / avaliação (REPL) hospedado no Visual Studio que pode executar o código F # conforme ele é escrito. O Visual Studio para Mac também oferece suporte total a projetos F #.
- O código do Visual Studio contém suporte total para F # por meio da extensão Ionide .
- F # pode ser desenvolvido com qualquer editor de texto. Existe suporte específico em editores como o Emacs .
- JetBrains Rider é otimizado para o desenvolvimento do código F # a partir da versão 2019.1.
- LINQPad tem suporte para F # desde a versão 2.x.
Áreas de aplicação
F # é uma linguagem de programação de propósito geral .
Programação da Web
A SAFE Stack é uma pilha F # ponta a ponta para desenvolver aplicativos da web. Ele usa ASP.NET Core no lado do servidor e Fable no lado do cliente.
Uma opção alternativa de F # ponta a ponta é a estrutura WebSharper .
Desenvolvimento de aplicativos multiplataforma
F # pode ser usado junto com as Ferramentas do Visual Studio para Xamarin para desenvolver aplicativos para iOS e Android . A biblioteca Fabulous oferece uma interface funcional mais confortável.
Programação analítica
Entre outros, F # é usado para programação financeira quantitativa, negociação de energia e otimização de portfólio, aprendizado de máquina, inteligência de negócios e jogos sociais no Facebook .
Na década de 2010, o F # foi posicionado como uma alternativa otimizada ao C # . A capacidade de script do F # e a compatibilidade entre idiomas com todos os produtos Microsoft o tornaram popular entre os desenvolvedores.
Scripting
F # pode ser usado como uma linguagem de script, principalmente para scripts de loop de leitura-avaliação de desktop (REPL).
Comunidade de código aberto
A comunidade de código aberto F # inclui a F # Software Foundation e o F # Open Source Group no GitHub . Os projetos F # de código aberto populares incluem:
- Fable , um transpiler de F # para Javascript baseado em Babel .
- Paket , um gerenciador de pacotes alternativo para .NET que ainda pode usar repositórios NuGet , mas possui gerenciamento de versão centralizado.
- FAKE , um sistema de compilação amigável ao F #.
- Giraffe , um middleware orientado funcionalmente para ASP.NET Core .
- Suave , um servidor web leve e biblioteca de desenvolvimento web.
Compatibilidade
O F # apresenta um "modo de compatibilidade de ML" legado que pode compilar diretamente programas escritos em um grande subconjunto de OCaml, sem functores, objetos, variantes polimórficas ou outras adições.
Exemplos
Seguem algumas pequenas amostras:
// This is a comment for a sample hello world program.
printfn "Hello World!"
Uma classe Person com um construtor que recebe um nome, idade e duas propriedades imutáveis.
/// This is a documentation comment for a type definition.
type Person(name : string, age : int) =
member x.Name = name
member x.Age = age
/// class instantiation
let mrSmith = Person("Smith", 42)
Um exemplo simples que costuma ser usado para demonstrar a sintaxe de linguagens funcionais é a função fatorial para inteiros de 32 bits não negativos, mostrada aqui em F #:
/// Using pattern matching expression
let rec factorial n =
match n with
| 0 -> 1
| _ -> n * factorial (n - 1)
/// For a single-argument functions there is syntactic sugar (pattern matching function):
let rec factorial = function
| 0 -> 1
| n -> n * factorial (n - 1)
/// Using fold and range operator
let factorial n = [1..n] |> Seq.fold (*) 1
Exemplos de iteração:
/// Iteration using a 'for' loop
let printList lst =
for x in lst do
printfn "%d" x
/// Iteration using a higher-order function
let printList2 lst =
List.iter (printfn "%d") lst
/// Iteration using a recursive function and pattern matching
let rec printList3 lst =
match lst with
| [] -> ()
| h :: t ->
printfn "%d" h
printList3 t
Exemplos de Fibonacci:
/// Fibonacci Number formula
let fib n =
let rec g n f0 f1 =
match n with
| 0 -> f0
| 1 -> f1
| _ -> g (n - 1) f1 (f0 + f1)
g n 0 1
/// Another approach - a lazy infinite sequence of Fibonacci numbers
let fibSeq = Seq.unfold (fun (a,b) -> Some(a+b, (b, a+b))) (0,1)
// Print even fibs
[1 .. 10]
|> List.map fib
|> List.filter (fun n -> (n % 2) = 0)
|> printList
// Same thing, using a list expression
[ for i in 1..10 do
let r = fib i
if r % 2 = 0 then yield r ]
|> printList
Um exemplo de programa Windows Forms:
// 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 x = 3 + (4 * 5)
new Label(Text = sprintf "x = %d" x)
// Add the label to the form
form.Controls.Add(label)
// Finally, run the form
[<System.STAThread>]
Application.Run(form)
Amostra de programação paralela assíncrona (CPU paralela e tarefas de E / S):
/// A simple prime number detector
let isPrime (n:int) =
let bound = int (sqrt (float n))
seq {2 .. bound} |> Seq.forall (fun x -> n % x <> 0)
// 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")
Veja também
Notas
Referências
- 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 # e C # , Manning Publications
- Hansen, Michael; Rischel, Hans (2013), Functional Programming Using F # , Cambridge University Press
- Astborg, Johan (2013), F # for Quantitative Finance , Packt Publishing
- Lundin, Mikael (2015), Testing with F # , Packt Publishing
links externos
- Site oficial The F # Software Foundation
- Grupo de código aberto F # no GitHub
- O Visual F # Developer Center
- Tsunami, um desktop F # IDE incorporável
- Cloud Tsunami, um Silverlight F # IDE incorporável
- Experimente F #, para aprender F # em um navegador da web
- Site de snippets F #
- O blog da equipe Visual F #
- O site original da Microsoft Research para F #
- Planeta F #
- The F # Survival Guide, dezembro de 2009 (livro baseado na web)
- A especificação da linguagem F #
- Uma introdução à programação em F #
- Um tutorial mostrando o processo de obtenção de um design funcional; inclui teste e codificação paralela