Codemountain, Paulo Suzart's Blog

Scala, Scala, Scala, em Java

with 3 comments

Isso, mais uma vez vamos falar do Scala, Scala, Scala. Este post rendeu. E rende até hoje pequenas discussões interessantes com amigos.

A diferença agora é que resolvi fazer a mesma coisa usando Java 1.5 com o auxílio da API Functional Java, que promete deixar o Java 7 com uma cara bem característica de Scala. Isso por conta da adição de Closure e outras características funcionais.

A API Functional Java vem sendo criada por Tony Morris, e pelo pouco que pude fuçar, está ficando bem interessante.

Eu não quero parecer tão ingrato com Java, afinal é a linguagem/Plataforma que garante o pão nosso de cada dia. Por isso vamos aos mesmo exemplo com esta tão querida linguagem que está tentando acompanhar a onda funcional:

1. Obter o quadrado de cada elemento em um List de 1 a 5.


import static fj.data.List.list;
import fj.F;
import fj.data.List;
//Observe os imports

private static final List<Integer> numbers = list(1, 2, 3, 4, 5);
//... aqui começa nosso método main

		List<Integer> c = numbers.map(new F<Integer, Integer>() {



			public Integer f(Integer arg) {

				return arg * arg;

			}

		});



		System.out.println(makeString(c, ",")); // {1,4,9,16,25}



A função map também está disponível na API, o que facilita muito. Note que o código é identico, o que muda é a verborágica syntax Java.😉 (Também é possível fazer com foreach de List que é outra opção quando não se quer criar uma segunda lista com os resultados).

2. Imprimir os elementos maiores que 3.

		List<Integer> gt3 = numbers.filter(new F<Integer, Boolean>() {



			public Boolean f(Integer arg) {

				return arg > 3;

			}

		});



		System.out.println(makeString(gt3, ",")); // 4,5

A API não possui a função reduceLeft nem reduceRight, mas podemos alcançar um resultado semelhante usando uma função que compõe as funções de reduce: folding. Aqui temos o foldLeft, uma função aplicada da esqueda para a direita para cada resultado esquerda operação direita. ou seja: 1 + 2 = 3 + 3 = 6 + 4 = 10 + 5 = 15 + 0, zero é o segundo argumento de fold. Mas sinceramente, fazer isso sem a promessa do Java 7 chega a ser cansativo.😦

Continuando com o último exemplo temos:

3. Soma de todos os elementos.

		final int b = numbers.foldLeft(new F<Integer, F<Integer, Integer>>() {

			public F<Integer, Integer> f(final Integer i) {

				return new F<Integer, Integer>() {

					public Integer f(final Integer j) {

						return i + j; 

					}

				};

			}

		}, 0);



		System.out.println(b); // 15

Filter e os métodos de 1 e 2 recebem um objeto do tipo F, que é uma interface com um único método chamado f, cuja implementação é por nossa conta.

Ah! o makeString é só um método statico para adicionar uma ‘,’ entre os elementos do list. Na listagem completa deste post você pode conferir este método que foi feito usando recursividade de uma forma bem exagerada pra fazer essa simples tarefa. Mas mostra como declarar funções dentro de funções faz muita falta em Java. Digo isso por que a função subMakeString não faz sentido algum sem a função printipal makeString, tornando nossa classe de exemplo com métodos sem muito nexo. A verdade é que fica bem ruim pra fazer certas coisas.

Construções desse tipo (com classes anônimas) já vem sendo usada há muito tempo, e eu particularmente gosto muito e uso, mas é cansativo de escrever tanta coisa, sem falar que em muitas situações é complicado para ler e entender o que se passa.

Resumindo, podemos construir uma ou outra coisa funcional com Java, e com auxílio de APIs como estas a coisa se torna mais interessante. Mas a syntax sempre vai nos surpreender negativamente como a grande vilã e o grande impecílio para o comportamento funcional em Java puro.  Além disso, note que os exemplos não são identicos, pois se fossem identicos, teriam muuuuuuuuito mais código. E afinal, vale a pena? Até que ponto esta linguagem suporta programação funcional se ela não se tornar de fato uma linguagem hibrida OO/Funcional?

O pessoal do Java tem que correr, pois muito se tem questionado a respeito da linguagem Java, do quanto ela já evoluiu e do quanto ela ainda poderá (?) evolir. Talvez, transformando a liguagem, ela ainda permaneça outa década no mercado, caso contrário, vamos continuar a assistir grandes sistemas sendo construídos em outras linguagens.

Dê uma olhada nesta API, os métodos para manipulação de lista com um pensamento funcional podem ajudar muitosuas  soluções no dia-a-dia.

Written by paulosuzart

março 23, 2009 às 10:48 pm

Publicado em Java, scala

3 Respostas

Subscribe to comments with RSS.

  1. “A API não possui a função reduceLeft nem reduceRight”

    We do on fj.data.Stream! We really should write it on fj.data.List as well — in the next release.

    Tony Morris

    março 24, 2009 at 5:29 am

  2. Your addition example can be shortened using fj.function.Integers.add.

    numbers.foldLeft(add, 0);

    Tony Morris

    março 24, 2009 at 5:31 am

  3. @Tony
    hummm! Excellent. I didn’t see this possibility (add). Congratulations, the API is really interesting.
    Thanks for comments.

    paulosuzart

    março 24, 2009 at 10:54 am


Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: