Programação funcional

Commom Lisp–Project Euler #1

2

Olá pessoal, seguindo a série de posts sobre commom lisp e a série de resoluções de problemas do projecteuler.net que os amigos Rodrigo Vidal, Elemar Junior e Juan Lopes estão fazendo aqui está minha contribuição do problema #1 em commom lisp.Vamos ao código:

A solução é bem menos elegante que a solução proposta pelo mestre Elemar em Haskell mesmo assim vamos analisar a solução.

Algoritmo

O algoritmo usado envolveu declarar uma função que recebe os limites, inferior e superior, e calcula os números cujo módulo de 3 ou 5 é igual a 0. Ao final da verificação de itens dentro do intervalo uma função que soma todos os valores resultantes foi aplicada.

Código
linha 2: o comando label foi usado para definir uma função que retorne uma lista com os números entre, inclusive, os  limites passados como parâmetro.

O loop for

Olhando bem para o uso do comando loop ele é um pouco diferente do restante do código lisp não é? afinal de contas um monte de palavras soltas não é normal em commom lisp. O comando loop é uma macro que permite diversas combinações de uso, olhe mais aqui.

linha 3: uma função múltiplo-de-3-ou-5 é definida, na função foi usado o comando (mod x y ) para verificar o módulo de um determinado número x por y.

linha 4: É onde o problema é realmente resolvido. Lendo o código da esquerda para direita temos o seguinte: uma função redutora que faz uso do redutor de soma “+” é usada para reduzir uma lista gerada pela função mapcar. A função mapcar aplicou a função ‘múltiplo-de-3-ou-5 na lista gerada pela função intervalo.

É isso pessoal, em breve vou  compartilhar mais soluções de problemas do ProjectEuler em lisp.

Números perfeitos em commom lisp

1

Olá pessoal, continuando a série de posts sobre Lisp hoje vamos ver uma possível resolução do problema números perfeitos. O problema foi escolhido na lista de  1001 algoritmos para implementar antes de morrer.

Resolução do problema

O problema foi resolvido usando TDD, então vamos começar pelos testes e códigos que fazem os testes passarem. O problema foi dividido em dois pequenos problemas, o primeiro deles é encontrar os divisores de um número, vamos ver os testes e solução:

Explicando o código
A primeira função diferente á a função labels, essa função deve ser usada para declarar funções internas a função a qual a função labels é chamada

Como usar:

 

Contextualização:
a função listar-divisores recebe apenas o número alvo como parâmetro, dentro da função uma função chamada  listar-divisores com dois parâmetros(numero divisores) é definida. O objetivo da função é percorrer todos os números até o número alvo(candidato a´número perfeito) e identificar se o número corrente é divisor do número alvo, caso seja o número será adicionado na lista. a função é executada enquanto o número for maior que 0

Condicional usando if
Commom lisp oferece diversos mecanismos condicionais, entre eles o if, o comando é bem simples, segue um exemplo que pode ser executado no REPL

Usando listas
Lisp fornece funções para trabalhar com lisp, algumas funções utilizadas foram:

São tão simples, que não é necessário comentar certo? Com esse código conseguimos fazer os testes passarem, então vamos definir mais testes e implementar mais uma função que deve finalizar o problema

O teste define que a função numero-perfeito deve retornar ‘(t) ou nil caso o numero seja perfeito  ou não.

Contextualização:
A implementação ficou simples, a grande jogada é usar a função reduce, o resultado da função definida anteriormente é uma lista de divisores, para fazer isso é necessário somar todos os itens da lista e comparar com o numero-alvo, caso seja igual o número é perfeito.

Reduce

o símbolo ‘+ é a função agregadora que será aplicada na lista dos divisores 

Pronto! Agora, todos os testes estão passando.

Conclusão
É isso pessoal, espero que tenham gostado. Estou escolhendo problemas simples para abordar a sintaxe de commom lisp. É sempre bom lembrar que provavelmente na linguagem em que você desenvolve na maior parte do tempo também é possível pensar de uma maneira um pouco mais funcional.

Quer aprender mais sobre commom lisp e/ou programação funcional?
http://lisp-br.org/
http://rodrigovidal.net/

Download do código de exemplo
https://bitbucket.org/higorcesar/exemploslisp

Sugestão para próximos posts
Ainda existem diversos assuntos para serem abordados, gostaria da sugestão de vocês para o próximo post sobre lisp/ programação funcional, os assuntos em pauta são:

  • Map/Reduce
  • Escalabilidade de software desenvolvido com base na programação funcional
  • Orientação a objetos em commom lisp CLOS

Iniciando com Lisp

0

Olá pessoal, desde o início da minha ainda breve carreira acredito que uma linguagem não é melhor ou pior que outra. Acredito que um programador profissional e apaixonado vai querer usar mais que um framework ou linguagem, já falei muito disso aqui. Seguindo essa linha de pensamento já estudei algumas linguagens famosas como Ruby, PHP e Python, a linguagem do momento é Lisp e pra ser mais exato commom lisp.

lisp

Lisp

Lisp é uma família de linguagens de programação concebida por John McCarthy em 1958. Num célebre artigo, ele mostra que é possível usar exclusivamente funções matemáticas como estruturas de dados elementares (o que é possível a partir do momento em que há um mecanismo formal para manipular funções: o Cálculo Lambda de Alonzo Church). Durante os anos de 1970 e 1980, Lisp se tornou a principal linguagem da comunidade de inteligência artificial, tendo sido pioneiro em aplicações como administração automática de armazenamento, linguagens interpretadas e programação funcional.

Wikipedia

Por que Lisp?
Lisp é uma linguagem funcional, que influencia implementação de diversas linguagens de programação e ainda possui uma sintaxe “complicada” que uma vez vencida a barreira torna o caminho do aprendizado de linguagens e paradigmas mais fácil.

 

Paralelismo
Antes de explicar a escolha da linguagem vou explicar a escolha do paradigma. Lisp é excelente para representar o paradigma funcional, a linguagem foi concebida tendo como base as definições e princípios desse paradigma. Hoje parte das linguagens apresentam características e recursos funcionais, quem é do “mundo .NET” já viu isso com LINQ e F#.A cada dia as soluções de software precisam aproveitar melhor a capacidade de processamento do hardware multi-core e os princípios propostos no paradigma funcional são excelentes para trabalhar com paralelismo.

 

Sintaxe Críptica
Entre as linguagens historicamente mais difundidas lisp é uma das linguagens com sintaxe mais complexa, Logo uma vez familiarizado com Lisp é possível obter conhecimento em paradigmas funcionais e de quebra se torna mais fácil aprender linguagens derivadas e influenciadas por lisp.


Não vou me alongar falando sobre benefícios e razões para aprender lisp, vamos ao código. Vou usar o Repl disponível aqui. Vamos começar pelo Olá mundo.

 

 

A função usada para definir uma função em lisp é defun, você precisa passar três parâmetros, o nome da função, parâmetros e corpo da função. A função defun é usada dentro de (), assim como muitos comandos em lisp.Sendo assim temos a seguinte estrutura:

Estrutura do método defun
Nome da função: ola-mundo
Parâmetros: nenhum
Corpo da função: ‘(Ola mundo)

 

Padrão de nomenclatura de funções

O padrão de nomenclatura de funções compostas em lisp é usar um hífen para separar as partes do nome, nada de Cases diferenciados ou underline.

Simbolos no lugar de texto
Programadores lisp evitam o uso de texto e na maior parte do tempo usam simbolos. O exemplo de código acima define um símbolo ‘(Ola mundo).

Ola mundo no estilo funcional
A função ola-mundo retorna um valor e não escreve dados na tela, a função retorna um símbolo e não possui side-effect. O código pode ser chamado inúmeras vezes que o resultado será o mesmo, essa é uma característica do paradigma funcional

 

Por hoje é só pessoal, esse post marca um novo rumo no quesito conteúdo do meu blog, iniciando por esse post esse blog deixa de ser um blog que so fala de linguagens do mundo .NET.Espero misturar posts semanais do mundo .NET e de outras linguagens, espero que gostem.

Go to Top