Archive for the ‘javascript’ Category

Refletindo sobre Tendências

Friday, July 10th, 2009

Recentemente muita gente tem me procurado nos instant messengers da vida para perguntar sobre tendências. Existe uma idéia no Brasil de que quem está de for a “traz as novidades”. Isso podia ser verdade antes da Internet mas agora as coisas se espalham com tanta velocidade que em muitos aspectos o Brasil está muito na frente da Austrália.

Mas existe o outro lado que é o trabalho na ThoughtWorks. Os projetos que nós enfrentamos geralmente começam da mesma maneira que os que qualquer consultoria, de três letrinhas ou três pessoas, enfrenta. O diferencial que faz ser um lugar interessante para se trabalhar é o que acontece durante o projeto.

O que segue neste post é uma amarrado de impressões pessoais sobre os últimos doze meses, tanto sobre a Austrália quanto o que sei de outros escritórios. Se ele não for coeso ou fácil de ler eu peço desculpas mas encare como um braindump.

Os projetos para bancos e empresas do mercado financeiro em geral continuam bem parecidos. Em 2007 houve uma euforia em torno da bolha econômica e muitos projetos megalomaníacos –e, por conseqüência, extremamente interessantes do ponto de vista técnico- apareceram mas a crise os tirou do baralho nos tempos recentes. Os bancos estão gastando menos e buscando fazer mais dinheiro reutilizando a estrutura existente. A maioria dos projetos que eu tenho conhecimento dentro de bancos é para estender uma determinada oferta para novos clientes ou é para migrar de uma plataforma legada para algo menos dispendioso.

O interessante sobre o “legado dispendioso”, dentro e fora de bancos, é que muitas vezes ele se trata de coisinhas como WebSphere, Aqualogic, Biztalk, Tibco e produtos parecidos. Apos gastar rios de dinheiro implantando estes e não ver nenhum centavo de retorno real muitos dos grandes estão migrando para plataformas mais eficientes, quase sempre baseadas em software livre. Hoje em dia são comuns projetos de migração de Websphere para Jetty ou de BizTalk para serviços RESTful usando IIS, JSON e ASP.Net MVC, por exemplo.

Na parte de aplicações para Internet, onde geralmente eu me envolvo mais, as coisas também têm mudado bastante. Basicamente os projetos têm se dividido em startups e legado. As startups aparecem com um problema e algum montante de dinheiro. A plataforma mais utilizada para atender estes cenários é Ruby on Rails, geralmente fazendo deployment em algum serviço de Cloud Computing.

Cloud Computing é um tópico extremamente relevante tanto para ThoughtWorks quanto nos nossos clientes. Uma das coisas interessantes que fizemos no início do ano foi trabalhar junto com o Google no lançamento da AppEngine em Java (e outras linguagens).

As empresas com legado de Internet são sempre interessantes. Geralmente elas são algum grande prestador de serviço na área de mídia e possuem um ou mais websites antigos que têm aquela arquitetura manjada de rodar em um Weblogic ou Tomcat com um Apache de front-end. O problema é que hoje em dia o numero de usuários é muito superior e a velocidade com que funcionalidades têm que ser adicionadas e alteradas é muito maior. Após entender que os Googles e Facebooks da vida não usam Java EE e não pagam licença para a IBM as empresas estão desesperadas para atingir o mesmo nível de eficiência.

O que temos feito nesta área é utilizar a já citada Cloud Computing para realizar tarefas que não precisam ser executadas dentro do firewall (de crawling até rodar teste de carga), refatorar aplicações grandes para atingir escalabilidade horizontal e simplificar processos de deployment e gerenciamento de recursos.

Na área mais de programação em si as coisas não têm sido lá muito excitantes. As plataformas em específico não têm nenhuma novidade marcante mas a programação poliglota é uma realidade. Até hoje todos os projetos que tive alguma participação dentro da ThoughtWorks utilizavam mais de uma linguagem de programação (já descontando Bash e JavaScript).

Uma surpresa agradável foi a que tive no meu projeto atual, em que voltei a programar em .Net após 3 anos afastado. A maioria das coisas que eu realmente não gostava sobre C# e seu ecossistema foram removidos (exceto Windows e Visual Studio, duas peças que eu considero de qualidade inferior). A Microsoft continua enfiando frameworks e ferramentas terríveis pela guela dos seus clientes (MSBuild? TFS? WCF? WTF?!?) mas no geral as coisas estão bem melhores.

Em termos de livros sobre programação eu tenho me focado quase que exclusivamente nos conceitos presentes em linguagens e paradigmas de programação. Esta é a lista de livros relacionados que eu li desde que cheguei aqui:



Esta é a fila dos que faltam:


(fora os que ainda estão no meu carrinho de compras na Amazon. Livro na Austrália é ridiculamente caro)

Na parte de gerenciamento de projetos e metodologias as coisas estão engraçadas. Tem horas que a euforia anima, tem hora que dá náusea. Eu acho que o Bellware resumiu muito bem:

early agile adopters were looking for a way to do things better. later adopters are just trying to do agile, thus the failures

Eu vim para a ThoughtWorks para ver como é que quem introduz métodos ágeis há anos trabalha. Nos últimos meses eu trabalhei com pessoas que fazem isto há mais de dez anos e em empresas que adotaram agile antes de eu saber que ele existia. O que eu aprendi neste período inicial é exatamente o descrito acima: quando seu objetivo é ser ágil você falha, quando seu objetivo é sempre melhorar você tem chances de sucesso.

Todos os projetos que participei foram bem sucedidos? Depende de para quem você pergunta. Mesmo os clientes mais difíceis que tive acabaram ficando satisfeitos no final mas muitos projetos que participei (e o número de projetos é bem maior que o número de clientes) foram executados de uma maneira que o time não ficou satisfeito. Eu acho que neste caso é perspectiva. Como a maioria dos projetos são um fracasso colossal basta ter algum nível de sucesso que o projeto vira referência. O time, em compensação, tem um critério de sucesso muito mais alto e não considera o projeto como bem-sucedido.

É claro que no fim das contas o que vale mais é a opinião do cliente –tanto porque o problema dele foi solucionado bem como porque é ele quem paga a conta no final- mas eu já vi diversos problemas decorrentes deste tipo de coisa. De builds que começaram em 10 minutos e terminaram em duas horas de duração até um time que perde 50% do seu tempo corrigindo defeitos por falta de uma suíte de testes decente. Os problemas podem não ser grandes para aquele projeto em específico mas não prestar atenção há eles é mortal em médio prazo.

Minha conclusão é que a indústria está num estado melhor do que há alguns anos atrás. Tecnicamente estamos entrando em uma espécie de renascimento e isso promete render muito material para posts aqui. Em termos de gerencia de projetos e processos as pessoas estão finalmente se convencendo que tudo tem limite, até ineficiência.

Ruby é JavaScript ao Avesso

Thursday, June 12th, 2008

O titulo é uma brincadeira mas é uma boa forma de lembrar algumas coisinhas sobre programação nestas linguagens. Cada vez mais lidamos no dia-a-dia com conceitos que estão presentes há décadas em linguagens mais esotéricas mas nunca deram as caras no mainstream, um deles é o uso de funções como abstração. Existe um conflito de termos aqui então só para deixar claro eu não estou falando de funções como em programação procedural mas sim de funções como vemos em closures.

Muita gente tem escrito sobre como devemos aprender programação funcional. Eu concordo mas não posso deixar de notar que quando alguém diz programação funcional geralmente ela quer dizer Higher-Order Functions.

E o que é isso? Bom, uma linguagem possui higher-order quando uma função pode receber como parâmetro outra função. O nome deriva do fato de que uma função que recebe outra é considerada de ordem 1, uma função que recebe outra que recebe outra é considerado 3 e assim em diante.

JavaScript possui higher-order programming. Funções são a abstração principal em javaScript e elas podem ser passadas à vontade pelo programa. Por exemplo, vamos supor que queremos comparar dois objetos de acordo com um critério arbitrário. Em JavaScript podemos fazer algo assim:

function melhorEntre(um, outro, criterio){
  if(criterio(um, outro)){
    return um;
  }
  else {
    return outro;
  }
}

sorvete1 = {sabor: 'morango'};
sorvete2 = {sabor: 'chocolate'};

prefiroChocolate = (function (s1, s2){
                                   return (s1.sabor === 'chocolate');
                            });

prefiroMorango = (function (s1, s2){
                                  return (s1.sabor === 'morango');
                            });

alert(melhorEntre(sorvete1, sorvete2, prefiroMorango).sabor);
alert(melhorEntre(sorvete1, sorvete2, prefiroChocolate).sabor);

Em Ruby o código ficaria um pouco diferente:

def melhor_entre(um, outro, criterio)
    if criterio.call(um, outro)
        um
    else
        outro
    end
end

sorvete_1 = { :sabor => 'chocolate' }
sorvete_2 = { :sabor => 'morango' }

prefiro_chocolate = lambda {|s1,s2| s1[:sabor] == 'chocolate'}
prefiro_morango = lambda {|s1,s2| s1[:sabor] == 'morango'}

puts melhor_entre(sorvete_1, sorvete_2, prefiro_morango)[:sabor]
puts melhor_entre(sorvete_1, sorvete_2, prefiro_chocolate)[:sabor]

Agora vamos pensar: as duas linguagens possuem higher-order programming? Não, só JavaScript possui. Em Ruby o que é passado não é uma função e sim um objeto, veja só:

prefiro_chocolate = lambda {|s1,s2| s1[:sabor] == 'chocolate'}
puts prefiro_chocolate
#=> #<Proc:0x00028a64@tmp/compara.rb:19>
puts prefiro_chocolate.class
#=> Proc

O principal divergente da solução em Ruby é que você deve passar a mensagem call para o objeto (ou usar a palavra-chave yield). Na pratica do dia-a-dia não tem tanta diferença e é comum falar em higher-order Ruby.

Em Ruby não precisamos de funções de verdade para termos higher-order programming, podemos usar objetos para modelar as funções. Em JavaScript não temos construções especiais para objetos, mas utilizamos funções:

function Sorveteiro(){
  this.numeroDeVendidos = 0;
  this.vender = function(){this.numeroDeVendidos++;};
};

s = new Sorveteiro();
alert(s.numeroDeVendidos);
s.vender();
alert(s.numeroDeVendidos);
s.vender();
s.vender();
alert(s.numeroDeVendidos);

Alguém me disse essa semana que uma das grandes vantaens em aprender higher-order programming (a pessoa falou em programação funcional mas não é bem isso que ela quis dizer) é que com ela você simula objetos mas o contrario não é verdade. Bom, não é assim. Nada impede de você ter higher-order programming em uma linguagem Orientada a Objetos (JavaScript é Orientada a Objetos!) e com objetos você pode facilmente modelar higher-order programming.

E qual a diferença disso tudo para programação funcional? Bom, programação funcional usa higher-order programming, mas não é isso que define uma linguagem funcional (JavaScript não é funcional).

Em 1984, John Hughes publicou um paper chamado “Why Functional Programming Matters”. Este paper é, até hoje, uma das obras mais importantes para o paradigma. Nele o autor descreve:

The special characteristics and advantages of functional programming are often summed up more or less as follows. Functional programs contain no assignment statements, so variables, once given a value, never change. More generally, functional programs contain no side-effects at all. A function call can have no effect other than to compute its result. This eliminates a ma jor source of bugs, and also makes the order of execution irrelevant - since no side-efect can change the value of an expression, it can be evaluated at any time. This relieves the programmer of the burden of prescribing the flow of control. Since expressions can be evaluated at any time, one can freely replace variables by their values and vice versa - that is, programs are “referentially transparent”. This freedom helps make functional programs more tractable mathematically than their conventional counterparts.

Erik Meijer apresentou uma palestra no JAOO chamada “Why Functional Programming (still) Matters” onde ele afirma que nenhuma linguagem é realmente funcional, provando que se pode simular efeitos colaterais em Erlang, Haskell, F# e várias outras.

A conclusão do Erik -é claro que defendendo suas decisões ao criar o LINQ- é que os conceitos por trás das linguagens ditas funcionais são mais importantes do que ser uma linguagem puramente funcional ou não.

Isso significa que você deve aprender sobre programação funcional e aplicar suas técnicas sempre que necessário mas cuidado com o termo “funcional”. Na maioria das vezes você quis dizer Higher-Order Programming.

Update: Alguns dos comentários msotram uma confusão com funções javaScript e objetos. Não só o texto falou que em JavaScript funções são objetos bem como ele mostrou o exemplo do sorveteiro, mas tentando deixar ainda mais claro:

ds