Aug 23 2010

O quanto realmente importa a escolha de uma linguagem?

Há alguns meses perguntaram ao Rich Hickey:

“How much does a choice of language really matter? Are there good reasons to choose one language over another or does it all come down to taste?”

E sua resposta foi:

“I think it matters quite a bit. A good language is opinionated, and strives to make a particular style of programming easy and idiomatic. It only seems a matter of taste when you are comparing languages that are more similar than they are different, like Java/C# or Python/Ruby. Try something really different like Clojure, Haskell, or Erlang and the fact that it matters becomes readily apparent.”

Eu acho que concordo bastante com sua opinião. Discutir se Java é melhor do que C#, por exemplo, é inútil, porque as duas linguagens são muito semelhantes. Nesse caso, o que acaba pesando mais na hora da escolha é o ecosistema no qual cada linguagem está inserida, que pode agradar mais a um ou a outro programador. É puro gosto.

O mesmo vale para Ruby e Python, como ele mesmo cita.

Mundos diferentes

Mas e se a comparação for entre Java e Ruby, por exemplo, como é que fica? Na minha humilde opinião, fica no sense. Porque Java e Ruby não são liguagens de mesma proposta; e mesmo sendo ambas de propósito geral, ambas tem objetivos claramente diferentes.

Comparação entre mundos diferentes

Agora vou, propositalmente, contradizer um pouco o que eu disse à cima: faz sentido, sim, você comparar Ruby com Java; Erlang com Python; F# com PHP. Sim, faz sentido.

Faz sentido quando você está escolhendo a linguagem que oferece a melhor solução para um dado domínio de problema.

Super CRUD com Erlang? Não, acho que não.

Precisar de concorrência massiva, tolerância a falhas, processos distribuídos, downtime mínimo? Humm, não sei não, mas será que não é de Erlang que você precisa?

Entende? É nessa hora que a escolha de uma linguagem começa a pesar de verdade. Isso realmente importa.

Mundos diferentes se complementam

Tempos atrás, escrevendo programas Erlang/OTP, senti falta de uma ferramenta que me ajudasse a criar rapidamente a estrutura inicial do projeto e umas coisas mais. O que fiz? Criei uma ferramenta que faz isso: otp_kickoff. Em Erlang? Não, em Ruby. Fiz isso em poucas horas, usando Thor.

Pouco tempo depois, senti falta de uma ferramenta de build amigável. Novamente, o que fiz? Criei o ebuilder, usando Ruby/Thor.

Um outro exemplo de mundos diferentes que se complementam é o JSparrow, um cliente de JMS bem fluente, que fiz usando JRuby.

Essa é a ideia de tirar o melhor de cada linguagem!

Mesmo porque, dificilmente, você constroi um sistema de verdade – que não seja um super CRUD – com apenas uma única linguagem de programação. Na minha equipe mesmo, há sistemas desenvolvidos em C# .NET, que são buildados, testados e deployados com Ruby/Rake/Cucumber e usam Java/Ivy como repositório de assemblies. Isso sem falar em JavaScript, que também tem de monte.

Esse é o mundo real dos sistemas de verdade.

Moral da história

Isso me faz pensar que brigas de fanboys de linguagens – em frenéticas buscas por prosélitos – são uma verdadeira piada.


Dec 28 2009

Geração e build de projetos Erlang/OTP

OK. Hora do jabá…

Há alguns meses, quando comecei a mexer mais com Erlang/OTP, senti a necessidade de ter uma ferramenta que gerasse a estrutura dos projetos, bem como stubs dos módulos necessários. Não encontrei nenhuma que fosse realmente simples. O que fiz? Cocei minha própria coceira, crie o projeto otp_kickoff.

Agora, de saco cheio desconfortável de usar Make para automatizar tarefas de build, resolvi coçar minha própria coceira novamente, crie o projeto ebuilder.

Se você também está mexendo com Erlang/OTP, sugiro que dê uma olhada nestes projetos, quem sabe eles também não facilitam sua vida, ahmmm?


Sep 6 2009

A Rails Rumble foi demais!

Se eu tivesse que descrever a minha impressão sobre a Rails Rumble em uma frase apenas, certamente, eu usaria o título deste post, porque pra mim, a Rails Rumble foi demais mesmo.

Não ganhamos a competição, mas ganhamos muito participando da competição. Aprendemos muita coisa, fizemos amigos, nos divertimos bastante e fizemos umas das coisas que mais gostamos de fazer: programamos pra caramba! – dormi aproximadamente 5 horas durante as 48 horas de competição.

Meus sinceros agradecimentos à galera do meu time: Anderson Leite (com quem pareei bastante), Rafael (que foi quem teve a brilhante idéia do projeto) e Douglas (o melhor sysadmin que eu conheço). Foi muito bom fazer parte do time com vocês.

Nosso projeto

Bem, o resultado final do nosso projeto é este: whatannoysus.com. Não é tudo que nós gostaríamos que fosse, mas com certeza, já é um ótimo começo – e vamos dar continuidade.

Nós o construímos em menos de 48 horas, usando Ruby on Rails, Cucumber e MySQL; e o botamos para rodar num Ubuntu Server com Phusion Passenger e Nginx.

Patrocínio

Vida longa à Gonow! :)

A Gonow nos tratou muito bem, com tudo do bom e do melhor. Comida, camiseta Rails Rumble, hotel (que eu nem fui lá conhecer) e uma infra-estrutura de primeira.

Muito obrigado mesmo, a todos da Gonow e, se precisarem de alguma coisa, é nóiz!

Poder aos pares!

Tenho que concordar com o Yoshima, parear traz um ganho incrível no desenvolvimento. Ainda tem muita gente que acha que parear é reduzir o trabalho pela metada, afinal, são dois em um computador. Mas a real é que boa parte do nosso trabalho como programadores é pensar e conceber soluções que, em última instância, codificamos. E é aí que entra o ganho da programação em parte: duas cabeças pensam melhor do que uma – e quatro olhos acham bugs mais rápido também.

Outros relatos?

É isso que eu [resumidamente] tinha a dizer. Se você quiser saber um pouco mais, conhecer outros relatos, veja os posts do Anderson Leite e do Rodrigo Yoshima. E se houver algo que eu não mencionei e que você gostariam de saber, sinta-se à vontade para deixar um comentário.

Vou ficando por aqui e espero poder rever toda a galera – que foi muito legal conhecer – na Rails Summit.

Abraço!


Aug 21 2009

Rails Rumble 2009: aqui vou eu!

http://www.gonow.com.br/rumble

Daqui a poucos minutos sairei aqui do meu trabalho em direção à Gonow para dar início à minha participação na Rails Rumble 2009, junto com meus camaradas @qmx, @r4f4el e @anderson_leite. A emoção está a mil, pode ter certeza!

Serão 48 horas de programação frenética, muita risada, descontração… e mais programação frenética — até o último git push.

Desde de já, quero agradecer demais a Gonow por todo apoio, que até camiseta e hotsite fez para todos fiquem realmente no clima da competição. Diego, valeu!

Torçam por nós!

@codezone
the_annoyers


Aug 2 2009

5 minutos de CouchDB e CouchRest

Normalmente demoro um bom tempo para escrever um tutorial completo, mas dessa vez vou tentar ser o mais breve possível, tanto ao escrever, quanto no resultado final.

O tema é CouchDB, o revolucionario banco de dados orientado a documentos e com interface totalmente RESTful, e a Ruby gem CouchRest, que é uma verdadeira mão-na-roda. Obviamente que, em tão pouco tempo — até para cumprir a promessa inicial –, eu não vou explicar os fundamentos do CouchDB, mas você pode encontrar uma introdução interessante aqui.

A primeira coisa que você precisa fazer é se certificar de que possui Ruby e CouchDB instalados. Caso você ainda não os possua, no Google você encontra inumeras receitas para todo sabor de sistema operacional. No meu caso, estou usando Mac OS X com Ruby EE da Phusion e CouchDB instalado via MacPorts — que acho a maneira mais prática de instação de qualquer coisa; esforço zero.


$ sudo port install couchdb

De qualquer forma, se você quiser uma fonte rápida de informação sobre instalação do CouchDB no seu sistema operacional, consulte o apêndice do livro CouchDB: The Definitive Guide. Lá você encontra um guia rápido para instalação em Windows, Mac OS X, Unix-like e a partir do fonte.

Mão na massa

Bem, com todos os pré-requisitos OK, vamos por a mão na massa logo de uma vez!

1- Instale a gem CouchRest

$ sudo gem install jchris-couchrest

2- Inicie o CouchDB

$ sudo couchdb -b

Acesse http://localhost:5984/_utils. Se você viu um camaradinha relaxando num sofá vermelho no canto superior direito da página, é porque está tudo certo com seu CouchDB. Vamos em frente.

3- Abra um terminal IRB

require 'rubygems'
require 'couchrest'

Tudo requerido corretamente, hora de começar a brincar com nosso banco de dados. Mas antes, vamos criá-lo!

db = CouchRest.database!('http://localhost:5984/my_db')

Agora vamos criar os atributos do documento que será gravado nesse banco.

attributes = { "name" => "Leandro Silva", "blog" => "leandrosilva.com.br", "titles" => ["System Architect", "Blogger"]}

Criado os atributos do documento, vamos gravá-lo.

result = db.save_doc(attributes)

Documento criado! Você pode acessar novamente http://localhost:5984/_utils e ver o que aconteceu até agora. Há um documento criado no banco my_db, com uma revisão apenas, contendo os dados que definimos no hash attributes.

Você também pode acessar informações resultantes da operação anterior através do hash result.

result['id']
result['rev']

Viu? São as mesmas informações que você viu no gerenciador web do CouchDB.

Vamos continuar acessando estas informações [de maneira absurdamente fácil] através da CouchRest.

record = db.get(result['id'])

Veja o hash record. Há duas chaves particularmente interessantes: _id e _rev. Estas duas chaves são equivalentes a id e rev do nosso hash anterior, o result.

Um teste? Compare os resultados abaixo.

result['id']
record['_id']
result['rev']
record['_rev']

Taí, simples assim. Viu a equivalência?

Vamos ver outros campos do nosso registro.

record['titles']

Que tal adicionar mais um titulo?

record['titles'] << 'Polyglot Programmer'

Bem, acho que já é hora de salvar e ir adiante, porque este tutorial tem que ser breve. Vamos lá.

result = db.save_doc(record)

Outra coisa interessante aqui. Vamos conferir a chave rev do nosso hash result.

result['rev']

Diferente da primeira vez que vimos, não? Vá ao gerenciador web do CouchDB e veja se algo mudou. Sim, algo mudou. Agora você tem a opção de navegar pelas revisões do seu documento. Fantástico!

Legal, muito bem por hoje.

db.delete_doc(record)

Agora volte ao gerenciador web do CouchDB e dê um refresh na página de visualização — caso você esteja nela.

O que aconteceu? Sumiu! O registro foi apagado.

Finalizando

$ sudo couchdb -d

Bem, por hoje é só pessoal. Espero que tenha sido realmente útil e que vocês tenham gostado.

Ah! E se gostaram, please, me deem um pontinho lá no WWRails. =p


Jul 30 2009

Quer saber onde será seu próximo trabalho?

Então não deixe de visitar…

O site é recém-nascido, mas já tem uns recursos bem legais, como sistema de pesquisa por palavras-chave, núvem de tags e entre outros. Vale a pena conferir e acompanhar sua evolução – e oportunidades de bons trabalhos.

Mais uma iniciativa bem interessante da Caelum. :)


Jun 2 2009

Sua gem funciona bem com JRuby?

Acabei de ler no post Notícias do Front #5 do Fábio Akita uma notícias que me deixou muito feliz:

is it jruby? – recentemente a Brightbox lançou o site is it ruby 1.9?, onde a comunidade poderia testar gems e dizer nesse site se ela é ou não compatível, em seus testes, com o ruby 1.9. Agora foi lançado mais uma com o mesmo objetivo mas desta vez para avaliar a compatibilidade de gems com o jruby. Mais e mais a comunidade está se conscientizando que as gems precisam receber mais tratamento para ficarem compatíveis com múltiplas virtual machines. Isso é muito bom e espero que todos colaborem.

Isto porque sou usuário de JRuby e volta e meia tenho problema com alguma gem que não funciona com ele, por conta de extensões nativas em C.

Então, por caridade, quando fizer uma gem, veja se ela funciona bem com JRuby também. :)


Apr 5 2009

Ruby + Rails no mundo Real 2009: Como foi?

Ontem aconteceu aqui em São Paulo o primeiro evento do GURU-SP, com co-participação da Tempo Real Eventos. Eu estive por lá e vou dizer - sob a minha ótica, claro - como é que foi.

Preço

O preço foi bem razoável para quem comprou antecipadamente, R$ 69,00; mas um pouco carinho para quem comprou na hora, R$ 129,00.

Local

O local, em geral, foi bom. Perto do metrô, pra quem foi de condução; estacionamento a R$ 10,00, pra quem foi de carro; opções de almoço perto não faltaram; o auditório acomodou todo mundo; o ar condicionado estava na medida certa; e o coffe-break, apesar de bem simples, também atendeu. No entanto não havia WI-FI. Isso foi realmente decepcionante, porque evento de programação, sem WI-FI pra galera que levou note, é russo.

Palestras

As palestras, sinceramente, me decepcionaram um pouco. Achei que foram muito introdutórias, muito superficiais. O que salvou o dia dos mais experiêntes foi a palestra do Fábio Kung e a do Caffo. Mas, sei lá, talvez tenha sido a estratégia do evento.

O track foi o seguinte:

1. Vinícius Baggio Fuentes: Criando um Instant Messenger usando Rails

XMPP é uma de minha áreas de interesse, então, estava realmente interessado nessa palestra.

O conteúdo estava legal, eu gostei do formato como a palestra foi estruturada, no entanto, acho que o Vinícius estava um pouco inseguro; e isso acabou atrapalhou um pouco em alguns momentos.

2. Hugo Lima Borges: Ruby, Rails e empreendedorismo

Esse é um assunto que tem sido muito recorrente em eventos de Ruby on Rails,  o que, com toda certeza, é um ponto muito positivo. Eu não me lembro de ter visto este tema rolar em eventos de Java, por exemplo. Mas a palestra, em si, achei meio frustrante pela superficialidade como o assunto foi abordado.

(Aliás, Hugo, você já empreendeu seu próprio negócio? Se sim, queria trocar umas figurinhas com você.)

3. Marcelo Castellani: Ruby no desktop

Não era para ser “Integrando Ruby e Java para facilitar a vida”?

Achei legal os comparativos e as dicas de quais toolkits funcionam melhor em cada SO, mas acho que faltou uma porção caprichada de código ao vivo. Código só no slide é um pouco chato. O legal é ver o código no slide, mas rodando no terminal também. Fica a dica.

4. Rodrigo Franco: Outsorcing, ou como trabalhar para empresas gringas

Para quem não sabe, esse cara é o Caffo, fundador da lista Rails-BR, que além de ser veiaco de Rails, também é muito experiente no que se propos a palestrar. Ele trabalhar com outsourcing, se não estou enganado, desde 2004.

Sua palestra foi muito, muito, interessante e todo mundo ficou muito intere$$ado mesmo. :)

A grande dia foi: Quer ser um pinguim com colar de ouro? oDesk.

Mas para isso, antes de mais nada, tenha uma conta ativa no GitHub; um blog que apenas copia notícias de outras fontes, mas que fala do que você pensa e sabe; uma página de portifólio e depoimentos também vai muito bem (segundo o Caffo, é indisponsável).

5. Mauricio Leal: GlassFish on Rails: Escalabilidade e Confiabilidade

Tema interessantíssimo para mim, uma palestra que eu estava realmente ansioso para ver. Acho que foi a que mais me decepcionou.

O Mauricio tem uma boa desenvolvura como palestrante, domina a oratória, mas sua palestra foi mais marketing - a Sun apoia Ruby, Rails e Open Source! - do que uma palestra técnica sobre o GlassFish. Como o próprio Fábio Kung, convidado pelo Mauricio, disse: O GlassFish é muito bom, mas o modo que a Sun tem o vendido à comunidade Ruby tem sido bem desadequada.

6. Carlos Brando: Só imaturos não testam

O Carlos é um cara que fala bem, sabe se expressar e sua palestra foi legal. Foi mais voltada a iniciantes em testes, mas bem legal. Na minha opinião, da próxima vez ele poderia abordar tópicos mais avançados de testes, cenários mais elaborados, etc.

Mas no geral, a palestra foi boa. Rolou até um marketzinho do Remarkable.

7. Willian Molinari: O que é e como funciona o RubyLearning

O RubyLearning é um site bem legal mesmo, ótimo não só pra quem está começando, mas para quem já tem algum conhecimento. Mas uma mini palestra para falar dele, não sei, não achei muito legal não. Acho que um post do tipo FAQ no RubyInside e no GURU-SP seria um apoio muito mais eficiente ao ótimo trabalho que o pessoal do RubyLearning tem feito.

Não posso deixar de dizer que o Willian, apesar de parecer bem jovem, soube conduzir muito bem a apresentação.

8. Fábio Kung: Ruby, muito mais do que reflexivo!

Palestra excepcional. O Kung realmente é um ótimo palestrante - instrutor da Caelum, não podia ser diferente.

A palestra dele abordou temas high level de metaprogramação com Ruby. ParseTree, Flog, roodi, Heckle e Ruby2Ruby foram alguns dos mandraques que ele nos apresentou. Foi o momento hacker do dia.

Ah! Além das ferramentas apresentadas, como o Carlos Brando, ele também fez marketing do seu projeto Rfactor.

Conclusão

Valeu a pena participar do evento, trocar idéia com os camaradas e tudo mais. Apesar dos pontos negativos, o resultado final é que o evento foi legal; e os pontos negativos ficam como um toque, para que o próximo evento seja ainda melhor.

Nos vemos no próximo evento!


Mar 8 2009

Sparrow, um cliente JMS baseado em JRuby

Mês passado comecei a tocar um projeto na CVC Turismo que, entre outras coisas, envolve troca mensagens assíncronas usando JMS. Esse trabalho foi está sendo tão divertido que me inspirou a escrever um post sobre Message-Driven Beans e Transações; e mais recentemente, a começar um novo projeto pessoal.

Sparrow é um cliente JMS implementado sobre JRuby e distribuido como uma Rubygem – hospedada no Github,  é claro. Ele é uma boa opção para quem precisa integrar sistemas Ruby com servidores de aplicações Java EE, provedores de mensageria JMS.

É pá, pum! Quer ver?

require 'rubygems'
require 'sparrow'

# Configuração que tem que ser feita uma única vez
jms_client = Sparrow::JMS::Connection::Client.new do |props|
  props.client_jar_file         = '/oc4j_extended_101330/j2ee/home/oc4jclient.jar'
  props.initial_context_factory = 'oracle.j2ee.naming.ApplicationClientInitialContextFactory'
  props.provider_url            = 'ormi://localhost:23791'
  props.security_principal      = 'oc4jadmin'
  props.security_credentials    = 'welcome'
end

jms_client.enable_connection_factories(
    :queue_connection_factory => 'jms/MyQueueCF'
  )

jms_client.enable_queues(
    :my_queue => 'jms/MyQueue'
  )

# Envio
jms_client.queue_sender(:my_queue).send_text_message('sparrow rocks!') do |msg|
  msg.set_string_property('recipient', 'sparrow-example')
end

# Recebimento
jms_client.queue_receiver(:my_queue).receive_message(
    :timeout  => 5000,
    :selector => "recipient = 'sparrow-example'"
  ) do |msg|

  puts msg.is_text_message?    # true
  puts msg.text                # sparrow rocks!
end

Fácil, não? :)

Se você quiser saber mais sobre o projeto, testá-lo, critica-lo, ou algo assim, por favor, não fique acanhado fique à vontade. E se não for pedir demais, deixe um comentário nesse post, como um feedback, para eu saber o quanto ainda preciso melhorá-lo e evoluí-lo.

Valeu!


Nov 3 2008

Sim, programação funcional é relevante hoje

Há um tempo tenho me interessado pelo paradigma de programação funcional, estudado e tentado aplicar vez ou outra algum de seus conceitos que faça sentido no domínio do problema que estou tentando resolver.

Com base nisso, resolvi escrever este post para dizer que, sim, programação funcional é relevante hoje, tanto quanto foi ontem – se não um pouco mais; e também dar uma visão geral sobre alguns de seus conceitos.

O que é programação funcional?

Segundo a definição de Paul Hudak em seu paper de 1989, “Conception, evolution, and application of functional programming languages”:

Programação funcional é um paradigma de programação que trata a computação como uma avaliação de funções matemáticas e que evita estados ou dados mutáveis. Ela enfatiza a aplicação de funções, em contraste da programação imperativa, que enfatiza mudanças no estado do programa.

Assim, praticar programação funcional consiste em definir funções e usar o computador como um avaliador de expressões. Aliás, uma característica predominante da programação funcional é que o significado de uma expressão é o seu valor, e o papel do computador é obtê-lo através da avaliação da expressão. Por exemplo, considere a expressão 2 + 3. Qual é o seu significado? 5. Agora, considere a expressão (2 x 2) + 1. Qual é o seu significado? 5. Ou seja, a avaliação nos faz concluir que as duas expressões significam a mesma coisa.

Outra característica básica e fundamental em linguagens funcionais é que funções são valores de primeira importancia, podendo estas serem usadas como parâmetro ou retorno de outras funções. Além do que, funções também são avaliadas como qualquer outra expressão matemática.

Aplicação do paradigma funcional

Programação funcional, obviamente, pode ser aplicada para resolver problemas de domínio matemático, mas não somente isso. Absolutamente!

Atualmente, muito do revival – se é que posso dizer assim – do paradigma de programação funcional se deve a aplicação dela no campo da concorrência, do processamento paralelo. Isso por conta de sua natureza stateless. É nesse campo que estão os grandes méritos de Erlang, e a motivação de F# e Scala. (Se bem que Scala pode, sim, trabalhar com estados. Quando a F#, eu não sei. Mas isso não importa muito agora.)

Há pouco ouvi falar também sobre uma bibliotéca fantástica para construção de interfaces gráficas escrita em Haskell, mas sinceramente nunca testei. (Na verdade, nunca escrevi uma só linha de código em Haskell.)

Exemplos de linguagens funcionais

Existe uma pancada uma grande número de linguagens funcionais, talvez muito mais do que você possa imaginar. Apenas para citar algumas: Lisp, Haskell, Scheme, XSTL, OCaml, Erlang, F# e Scala. Mas, acredite, há muitas outras!

Conceitos funcionais em código

Como esse é um blog de programação, e estamos falando de programação, quero explicar rapidamente alguns conceitos de programação funcional exemplificando em código.

1- Lambda Calculus

O principal fundamento da programação funcional é a teoria Lambda Calculus, cuja qual podemos encontrar a seguinte definição na Wikipedia:

In mathematical logic and computer science, lambda calculus, also written as λ-calculus, is a formal system designed to investigate function definition, function application and recursion. It was introduced by Alonzo Church and Stephen Cole Kleene in the 1930s as part of an investigation into the foundations of mathematics, but has emerged as a useful tool in the investigation of problems in computability or recursion theory, and forms the basis of a paradigm of computer programming called functional programming.[1]

The lambda calculus can be thought of as an idealized, minimalistic programming language. It is capable of expressing any algorithm, and it is this fact that makes the model of functional programming an important one. Functional programs are stateless and deal exclusively with functions that accept and return data (including other functions), but they produce no side effects in ‘state’ and thus make no alterations to incoming data. Modern functional languages, building on the lambda calculus, include Erlang, Haskell, Lisp, ML, Scheme, Scala and F#.

Entendemos então que, em programação funcional, funções são abordadas no puro sentido matemático. A definição da Wikipedia para Lisp diz:

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).

Via de regra, toda linguagem funcional oferece algum tipo de construção para cálculo lambda.

Por exemplo, considere a seguinte função matemática:

f(x) = x + 30

Em Scala, ela poderia ser escrita assim:

val f = (x: Int) => x + 30
f(5)   // 35

Ou mesmo em Ruby, que apesar de não ser funcional, oferece suporte a algumas abordagens desse paradigma, poderia ser escrito assim:

f = lambda {|x| x + 30}
f[10]   # 40

2- High-order function

High-order functions são funções que podem receber outras funções como parâmetro, e também retorná-las como resultado. A estas damos o nome de função de primeira classe. Essa é uma característica extremamente importante em linguagens funcionais. Vejamos um exemplo:

def escolhido(a: Int, b: Int): Int = if (a >= b) a else b

def imprEscolhido(f: (Int, Int) => Int, a: Int, b: Int) =
println("O escolhido foi: " + f(a, b))

...

// usando a função escolhido
imprEscolhido(escolhido, 1, 5)   // 5

// usando uma função anônima
imprEscolhido((x: Int, y: Int) => x, 12, 2)   // 12

2- Currying

Currying é a técnica de transformar uma função que recebe multiplos argumentos de maneira que ela possa ser chamada como uma cadeia de funções, com apenas um argumento por vez. Na prática, o que acontece é que a cada chamada a uma função da cadeia, uma nova função é retornada.

Vamos ver um exemplo que pode ser encontrado na integra no site A Tour of Scala:

// cria uma função para filtrar uma lista
def filter(xs: List[Int], p: Int => Boolean): List[Int] =
  if (xs.isEmpty) xs
  else if (p(xs.head)) xs.head :: filter(xs.tail, p)
  else filter(xs.tail, p)

// cria uma função "módulo" para ser usada no filtro,
// por isso ela retorna "true" ou "false"
def modN(n: Int)(x: Int) = ((x % n) == 0)

// cria uma lista com números de 1 a 8
val nums = List(1, 2, 3, 4, 5, 6, 7, 8 )

// imprime aplicando módulo em 2
println(filter(nums, modN(2)))   // List(2,4,6,8)

// imprime aplicando módulo em 3
println(filter(nums, modN(3)))   // List(3,6)

Se você não está familiarizado com código Scala, não se preocupe, à primeira vista parece meio esquisito mesmo. Por isso, não se atente aos detalhes. O importante aqui é você entender que a saída desse programa depende:

1º) Do número que é aplicado ao primeiro argumento (n) da função modN, quanto ela é chamada e o seu resultado passado como argumento à função filter – pois o seu resultado será uma “nova função” que receberá apenas o segundo argumento (x) que ela definiu;

2º) Do número que a função filter aplica ao único argumento que a função p (que é resultado da chamada a modN) aceita.

Ou seja, é como se a função modN tivesse seus dois argumentos parcialmente informados em dois momentos diferentes, tornando a sua chamada muito mais simples e flexível. Essa é a idéia da cadeia.

Vamos um ver outro exemplo, ainda em Scala, talvez um pouco mais simples:

// cria uma função que retorna "outra função" que recebe
// apenas o segundo argumento desta
def idadeAceita(m: Int)(i: Int): Boolean = i <= m

// ao ser chamada, a função idadeAceita retorna uma "nova
// função" que dei o nome de aplicarIdade e recebe apenas
// o segundo argumento definido por idadeAceita
val aplicarIdade: (Int) => Boolean = idadeAceita(18)

...

aplicarIdade(14)   // true
aplicarIdade(40)   // false

Acho que esse exemplo fala por si e dispensa maiores explicações. :)

Não é interessante como os diversos conceitos abordados até aqui vão se completando?

Que mais?

Bem, tudo que eu disse nesse post gigante é apenas uma visão geral. Talvez a pontinha do iceberg. Então espero que ele te motive a estudar um pouco mais sobre programação funcional. (O texto está repleto de links para outros texto interessantes.)

Valeu!