
Prefácio
Este é um livro sobre a linguagem de programação OCaml e sobre o paradigma de programação funcional. Não faz tanto tempo, o autor de um livro como este teria de gastar um número muito maior de palavras justificando para o leitor por que ele deve empreender um esforço para sair da sua zona de conforto e aprender um novo paradigma.
Hoje em dia, essa tarefa é muito mais fácil, quando consideramos as tendências atuais no universo do desenvolvimento de software. Cada vez mais, a indústria de software se convence das vantagens do paradigma funcional, e muitas das novas e promissoras ideias sobre programação que apareceram nos últimos anos vieram da comunidade da programação funcional.
A Orientação a Objetos (OO) ainda é dominante e continua sendo amplamente usada, mas parece um pouco estagnada: poucas novas ideias parecem estar surgindo desse paradigma. A maior parte das novidades nas novas versões de linguagens populares, como Java, C# e C++, tem inspiração funcional.
Um exemplo são os lambdas (funções anônimas que geram closures) adicionados na versão 8 do Java e no padrão C++11. A cada nova versão, o JavaScript ganha mais e mais características funcionais. Os dois principais ecossistemas para aplicações gerenciadas, as plataformas Java e .NET, ambos possuem uma ou mais linguagens primariamente funcionais de crescente popularidade; Scala e Closure no caso da plataforma Java, e F# em .NET. F# começou basicamente como uma versão de OCaml para a plataforma .NET.
Novas linguagens como a Rust, criada pela Mozilla, a Swift, criada pela Apple, e a Hack, criada pelo Facebook, carregam também uma grande influência funcional. Por sinal, o compilador de Hack é escrito em OCaml. Para programadores que desejam se manter atualizados e em contato com as boas práticas da indústria, fica cada vez mais difícil evitar a programação funcional.
Entretanto, embora já exista um bom número de livros sobre linguagens funcionais disponíveis em inglês, tanto livros mais acadêmicos quanto mais práticos, as opções na língua portuguesa ainda são escassas. Este livro procura preencher essa lacuna, mas de forma menos acadêmica e mais pragmática.
A forma mais prática de aprender um paradigma é se aprofundando em uma linguagem importante desse paradigma. Daí este livro, OCaml: programação funcional na prática.
Por que "na prática"?
Muitos livros sobre programação funcional são livros-textos criados para serem material didático em disciplinas sobre programação funcional ou paradigmas de linguagens de programação. Isso não é um problema em si; muitos desses livros-textos são excelentes e valem a pena serem lidos. Entretanto, eles frequentemente incluem tópicos que, embora sejam interessantes, não são essenciais para quem quer programar em uma linguagem funcional.
Um exemplo é falar sobre o lambda-cálculo, que é o fundamento teórico das linguagens funcionais; é um tópico interessante, mas não necessariamente essencial para programadores iniciantes no modelo. Por outro lado, existem características de OCaml que não são tradicionais nos cursos sobre programação funcional, mas que são frequentemente usadas na prática pelos programadores; dois exemplos são os parâmetros rotulados e as variantes polimórficas.
Este livro é prático porque foi escrito pensando no leitor como um programador interessado em OCaml e no paradigma funcional, não necessariamente um aluno de algum curso. A intenção é equipar o leitor para ler código escrito pela comunidade da linguagem e para criar projetos de seu interesse em OCaml, além de mostrar seus princípios fundamentais.
Livros-textos tendem a um enfoque maior nos princípios e na teoria, e menor nos detalhes de linguagens específicas. Como um grande tópico, a programação funcional é maior do que apenas OCaml (e OCaml não é apenas funcional), mas consideramos que a melhor forma de aprender um paradigma mais a fundo é se aprofundar em uma linguagem específica desse paradigma. Essa é a intenção deste livro.
Desta forma, o livro inclui várias dicas e sugestões de como usar OCaml de maneira mais efetiva, além de observações sobre o que é e não é idiomático na linguagem, de acordo com o código que é produzido pela comunidade de usuários. Embora o livro não cubra algumas características mais recentes e avançadas, a intenção é de que quem leia o livro inteiro tenha condições de entender 90% ou mais do código escrito em OCaml que pode ser encontrado na internet.
Os tópicos cobertos no livro foram escolhidos com essa intenção. Com essa base coberta, os leitores mais interessados poderão aprender os aspectos mais profundos da linguagem nos manuais ou em outros materiais.
Este livro também é prático porque inclui, além de vários exemplos pequenos que ilustram características específicas, alguns exemplos maiores de programas relativamente realistas em OCaml. Esses exemplos demonstram, ao mesmo tempo, alguns domínios em que a programação funcional se sai bem, e áreas de aplicação que são interessantes para um programador.
O código-fonte desses exemplos é criado e organizado de uma maneira comum para projetos em OCaml, ilustrando como algumas ferramentas presentes no ecossistema da linguagem (por exemplo, ferramentas de build e de teste) são usadas em projetos reais. Dessa forma, o leitor pode usar os exemplos mais longos como modelos (em termos de organização e ferramentas utilizadas) para seus próprios projetos.
O que se espera do leitor e o que o leitor pode esperar do livro
O presente livro foi escrito pensando no leitor como um programador com alguma experiência em linguagens imperativas/OO, mas que não teve contato anterior com o paradigma funcional, ou teve um contato apenas superficial. Esse ponto de referência é utilizado para centrar as explicações ao longo do texto.
OCaml não é uma linguagem minimalista nem tem a pretensão de ser "simples"; é expressiva e poderosa com um conjunto considerável de features adicionadas por cima do núcleo funcional da família ML. A sequência de capítulos do livro pretende introduzir a maior parte dessas features em uma ordem que faça sentido para um iniciante na linguagem.
Ao fim do capítulo "Programação funcional", o leitor terá visto todo o núcleo funcional; o fim do capítulo "Características imperativas" marca a exposição completa do que podemos chamar de núcleo básico das linguagens ML. Exceto por diferenças sintáticas, esse núcleo é praticamente o mesmo em OCaml, Standard ML e F#, três linguagens da família ML.
A partir daí, passamos a cobrir características mais avançadas de OCaml e que a tornam mais única dentro de sua família. No meio dos capítulos introduzindo novas partes da linguagem, temos dois com estudos de caso, mostrando programas mais substanciais em OCaml: um dos capítulos mostra um compilador, um interpretador e uma máquina virtual para linguagens simples; o outro mostra como analisar dados e como empregar técnicas de aprendizado de máquina para classificar informações automaticamente.
A forma recomendada de ler o livro, como qualquer outro livro de programação, é ativamente: tentando os exemplos, fazendo perguntas ao texto (e tentando respondê-las com experimentação), usando o que foi introduzido para escrever alguns programas pequenos mas interessantes etc. Como disse Aristóteles, aquilo que devemos aprender a fazer nós aprendemos fazendo.
Sumário
- 1 Introdução
- 1.1 Por que programação funcional?
- 1.2 Características de OCaml
- 1.3 Por que OCaml?
- 1.4 Usos e aplicações
- 1.5 O sistema OCaml
- 1.6 Organização do livro
- 2 Tipos e valores básicos
- 2.1 Primeiros passos
- 2.2 Variáveis e tipos básicos
- 2.3 Funções
- 2.4 Tipos agregados
- 3 Registros e variantes
- 3.1 Sinônimos de tipos
- 3.2 Registros
- 3.3 Variantes simples
- 3.4 Variantes com valores associados
- 3.5 Tipos recursivos
- 3.6 Árvores
- 4 Polimorfismo e mais padrões
- 4.1 As listas predefinidas
- 4.2 Mais sobre padrões
- 4.3 Árvores polimórficas e valores opcionais
- 5 Programação funcional
- 5.1 A essência da programação funcional
- 5.2 Mutabilidade e outros efeitos
- 5.3 Programação recursiva
- 5.4 Funções de primeira classe
- 5.5 Padrões de recursividade
- 5.6 Tipos como fonte de informação
- 5.7 Dois operadores para aplicar funções
- 5.8 Funções de alta ordem em árvores
- 6 Exemplo: interpretador e compilador
- 6.1 Expressões aritméticas
- 6.2 Interpretação
- 6.3 Uma máquina de pilha
- 6.4 Compilação
- 6.5 Otimização
- 7 Características imperativas
- 7.1 O tipo unit
- 7.2 Entrada e saída
- 7.3 Sequenciamento de expressões
- 7.4 Atualização funcional de registros
- 7.5 Registros com campos mutáveis
- 7.6 Referências
- 7.7 Arrays
- 7.8 Estruturas de controle imperativas
- 7.9 Exceções
- 8 Módulos
- 8.1 Estruturas e assinaturas
- 8.2 Acesso aos itens de um módulo
- 8.3 Módulos e arquivos
- 8.4 Funtores
- 8.5 Extensão de estruturas e assinaturas
- 8.6 Módulos de primeira classe
- 9 Exemplo: árvores de decisão
- 9.1 O problema do Titanic
- 9.2 Um pouco sobre aprendizado de máquina
- 9.3 Inferência de árvores com ID3
- 10 Parâmetros rotulados
- 10.1 Rótulos para nomear parâmetros
- 10.2 Parâmetros opcionais
- 10.3 Inferência de tipos e funções de alta ordem
- 10.4 Sugestões para o bom uso de rótulos
- 11 Variantes polimórficas e extensíveis
- 11.1 Limitações dos tipos variantes
- 11.2 Variante polimórficas
- 11.3 Variantes extensíveis
- 11.4 Variantes de tipos variantes
- 12 Um pouco sobre objetos
- 12.1 Objetos
- 12.2 Classes
- 13 Organização de projetos e testes
- 13.1 Organização do projeto com OASIS
- 13.2 Testes com OUnit
Dados do produto
- Número de páginas:
- Data publicação: