Criei no github um pequeno módulo JavaScript para implementar o conceito de tipo Optional. Opcional foi por sua vez inspirado no tipo monadico Maybe do Haskell. Monads são abstrações funcionais para tratar de computações indeterminísticas, ou seja com um resultado incerto mesmo dadas as mesmas entradas (p ex. consulta a um banco de dados, leitura de um arquivo). De fato todos os programas Haskell rodam em uma gigantesca monad IO que é a função main. A Monad que estamos implementando (faltam algumas funções para ser uma monad completa) que é a opcional, no caso trata de alguma atribuição que pode retornar valores nulos.
Modo tradicional de tratar nulos em Java:
void doSomethingWithX(X x){
if(x != null){
x.doSomething()
}
}
NullPointerException é uma exceção extremamente comum em Java, isso porque além das tradicionais fontes de indeterminismo como as citadas acima, temos os próprios desenvolvedores que instanciam objetos mas não inicializam seus atributos e principalmente o padrão JavaBeans que permite o adiamento da inicialização, algo que não pode ser restringido agora dados os inúmeros frameworks que dependem de classes com construtores sem argumentos e métodos set públicos. Em linguagens como C/C++ a criação indiscriminada de objetos não inicializados é uma heresia e fonte dos erros mais nefastos que já existiram na computação mas em Java ou mesmo há o conforto dos coletores de lixo.
Mas no mundo funcional há um jeito mais elegante que é o tipo Opcional (Option em Scala, Optional em Java 8, Maybe em Haskell) que é um valor que pode ser nulo. O funcionamento é simples, há uma função Unidade, que recebe o valor (seja ele nulo ou não) se o valor for existente (não nulo) ela retorna o valor encapsulado em um objeto (chamado Some em Java 8/Haskell e Something em Scala, Unidade em Portugol). Daí a função de alta ordem conhecida como map recebe uma função de um único argumento com retorno, o argumento é do mesmo tipo do valor esperado no opcional e o retorno é um tipo arbitrário. No caso de um opcional vazio (Nothing em Scala, None em Haskell e EMPTY em Java) que representa um valor nulo o map é uma no-op, só retorna o mesmo opcional vazio e um opcional com valor retorna outro opcional que encapsula o valor retornado pela função-argumento de map (se esse valor for nulo é retornado um opcional vazio).
Agora, uma linguagem vastamente utilizada chamada Javascript acertou desde o começo no sentido de que tem funções de primeira classe, mas o tratamento de nulos ainda é feito do modo rudimentar, com if-else. Por isso eu criei o script opt.jsque faz exatamente o que eu falei neste longo testamento.
Contemplem o poder da programação funcional, todos aqueles if-else transfomaram-se em funções de ordem elevada, meta-funções, o desenvolvedor só precisa passar a função que representa a lógica desejada (lógica de negócios). As meta-funções encarregam-se da lógica de encanamento (pumbling), ou seja tudo aquilo que não é lógica de negócios e serve tão somente para manter o programa rodando.
Observem que:- opt é a função unidade
- Os tipos Vazio e Unidade (carrega um valor não nulo) foram copiados do Haskell Some e None
- Ainda falta a função/operação bind para que isto seja uma Monad completa
Nenhum comentário:
Postar um comentário