Archive for the ‘c++’ Category

Modelo de Negócios e Tecnologia

Sunday, December 2nd, 2007

Há alguns anos eu trabalhava para uma grande empresa que cria produtos em um nicho muito específico. Dá última vez que eu vi alguém fazer uma estatística 90% dos produtos eram em C, 5% em C++ (”muito lenta”) e o restante em PERL, Python e Java.

A coisa que eu mais gostava sobre essa empresa era como o modelo de negócios deles era movido por inovação. Quando alguém tinha uma boa idéia ele era convidado a montar um protótipo em laboratório que seria oferecido à clientes. Haviam muitos ganhos para os bem-sucedidos, meu chefe, diretor regional de tecnologia, subiu ao seu cargo após duas idéias convertidas em produto (além de ganhar uma boa grana).

No entanto, apesar da inovação presente nos novos produtos lançados simplesmente não havia inovação técnica. Não importa o software, tudo era feito em C. Eu fui contratado para um novo time que cuidava das alicações Java. Estas aplicações só foram criadas porque os clientes exigiam interfaces web e RMI para os produtos da empresa e porque contratar programadores C sempre foi um problema. Mesmo trabalhando basicamente com Java (e naquela época o sonho de todo mundo era arrumar um emprego “100% Java, nada de PHP ou VB”) boa parte do meu trabalho era escrever e testar interfaces em C que se comunicavam com o sistema “de verdade” (o feito em C).

Certa vez me mandaram por 10 dias, que viraram 20, numa viagem de trabalho. O lugar não era muito amigável com turistas então passei boa parte do tempo no quarto de hotel tentando entender a televisão. Como não tinha Internet liberada eu passava no dia baixando PDs e páginas completas para ler à noite e nos fins-de-semana. Com o tempo pensei: e se eu reconstruisse o sistema em Java? Obviamente que não consegui reproduzir o sistema todo dado o tempo mas se o sistema antigo tinha 5% em Java eu consegui que fosse unas bons 30%. Chegue no escritório doido para mostrar ao meu chefe.

Obviamente foi um banho de água fria. A pessoa ficou feliz por eu me interessar pelos projetos internos e disse que iria ver o sistema, um dia. Esse dia nunca chegou. Após alguns meses eu pedi demissão da empresa.

Dia desses estava falando com um amigo que ainda trabalha lá e soube que 50% dos clientes foram embora. Na época que eu trabalhava nessa empresa ela tinha quase que o monopólio de um dado tipo de sistema, com tempo concorrentes foram surgindo. O sistema da empresa era claramente superior aos outros mas era muito menos flexível. Ele era muito bom no que fazia mas quando precisávamos que ele fizesse a coisa um pouquinho diferente o projeto durava meses. Os concorrentes chegaram com linguagens como C++ e Java e apesar de não terem um produto com 10 anos de bons serviços prestados eles conseguiam mudar rapidamente.

Há dez anos a escolha por utilizar C e IPC de UNIX na mãozona era certa. Nenhuma plataforma da época oferecia o desempenho aceitável. Infelizmente as pessoas acabam construindo as piores coisas do mundo com desculpa de performance e o sistema era completamente monolítico e depende tanto do SO que mudar de uma versão minor para a outra leva um ano com um time de 3 pessoas completamente dedicados.

Se esta empresa acompanhasse os movimentos da indústria veria que existiam plataformas que já ofereceriam performance aceitável (eu já trabalhei em sistemas Java mais eficientes que aquele em ouros lugares) e que iriam oferecer a flexibilidade necessária. Infelizmente só repararam isso quando a concorrência invadiu o mercado.

A empresa continua com produtos ótimos em suas idéias mas ninguém consegue esperar 2 anos para colocar algo no ar. As coisas mudaram e escolher a tecnologia certa para cada caso é cada vez mais o qe define sucesso ou fracasso de um projeto. Ou de uma empresa.

Construindo Expressividade com Linguagens Elegantes

Friday, July 27th, 2007

Ainda não vi uma definição sobre o que seria uma linguagem elegante, então lá vai a minha:

Uma linguagem elegante é baseada em primitivas simples e extensíveis e, principalmente, sem muitas exceções.

Segundo esta definição Ruby, Smalltalk e LISP são elegantes. Java é um pouco, C# com suas centenas de exceções (sobrecarregar + é diferente de sobrecarregar [], dentre outras várias exceções) não é.

Uma linguagem elegante é simples e compacta. É de se esperar que não tenha sobrecarga de operadores, mas isso não é verdade. O problema das pessoas com sobrecarga de operadores é porque elas vêem isso como uma quebra da rule of least surprise. Essa regra diz (implora, eu diria) para não surpreendermos nossos usuários modificando o mundo que eles já conhecem para que uma ação traga consequências não esperadas. Por exemplo imagine que você vai modificar um programa como o ls para dar mais performance (uau, você é bom!). Faça o que quiser mas não mude os parâmetros de entrada e saída ou você vai quebrar um zilhão de programas e scripts pelo mundo todo. Caso introduza uma feature nova faça o usuário explicitamente solicitar por ela (passando um flag no estilo ls -lira –my-fancy-new-feature) e mantenha o default como o antigo.

E onde entra sobrecarga de operadores nisso? Lá no seu primeiro curso de programação (ou no seu primeiro livro se você opta pelo caminho mais difícil) deve ter aprendido sobre literais, variáveis, condicionais e… operadores. Operadores são caracteres especiais com uma função bem definida na linguagem, por exemplo o operador de divisão, de resto, de adição…

Em Java, quando você chama:

String texto = "abc".toUpperCase();

É fundamentalmente diferente de quando chama:


int numero = 12 + 24;

Porque um método e um operador são coisas diferentes e você aprendeu a pensar desta forma. Se amanhã eu puder sobrescrever o operador + para que escreva algo na tela você vai se surpreender porque não era isso que o manual da linguagem te disse.

Ainda assim, existem muitas ocasiões onde sobrecarga de operador são mais que convenientes, são semânticos. Imagine o exemplo do nosso BigDecimal:


BigDecimal a = new BigDecimal("100");
BigDecimal b = new BigDecimal("300");

Some os dois. Ok, você é um programador Java esperto e sabe que vai ter que fazer algo como:


BigDecimal resultado = a.add(b);

Mas disso até me dizer que é melhor que usar ‘+’ é outra história.

Mas e a simplicidade? Não é legal termos um conjunto pequeno de operadores que faz coisas previsíveis e que servem na maioria das vezes? Sim, é! Mas num mundo onde tudo migra para mais expressividade, com Model-Driven Development e Domain-Specific Languages ter este tipo de limitação não é interessante. As melhores linguagens para construir DSLs são as mais flexíveis e por acaso as mais elegantes, que coincidência, não? E como Ruby, que se enquadra nestes dois aspectos, lida com isso?

Simples. Em Ruby não existem operadores, pelo menos não como você está acostumado em Java, operadores são apenas apelidos para métodos. A vantagem disso é que se muda o modelo mental, a partir do momento que você sabe que um operador e um método são a mesma coisa você tem com operadores o mesmo cuidado que tem com métodos. Ao chamar add() do BigDecimal você tem que saber se o método vai retornar o resultado como um objeto separado, se vai modificar os objetos passados como parâmetros, etc. Como você faz isso? Lendo a documentação até se familiarizar com a classe e seu idioma. Após familiarizado você começa a usar sem pensar.

E quando você espera estar lidando com uma classe que sobrescreve um operador e na verdade recebe como parâmetro uma subclasse dela? Sem problemas! Se o autor seguiu os princípios básicos da Orientação a Objetos, que derivam do Design by Contract e o Princípio de Substituição de Liskov a subclasse tem que obedecer o contrato da classe-pai, e se você obedeceu os mesmos princípios não precisa de nada que não esteja no contrato.

Esse tipo de resistência com funcionalidades é o tipo de coisa que se elimina aprendendo várias linguagens e estudando suas motivações. Existem algumas linguagens como as citadas que merecem ser estudas ainda que você nunca as vá utilizar de fato. Elas abrem a sua cabeça.

Ele Não Aguenta Mais Arroz Com Ovo

Monday, May 7th, 2007

Continuando na nossa série de alertas (não, não era uma série mas acabo de inventar isso) chegamos a um excelente texto sobre o futuro de java x .Net no infoQ. Deste eu destaco:

When .NET was first released in 2000/2001, the Java community considered it a “clone” of Java, both language and standard library. Comparing simple code samples surely support this impression. However, MS profited from many years of experience with Java, and managed to solve some issues that Sun only now realizes as problems. The impression that the .NET and the CLR are evolving faster than Java is not lost on the Java community.

Other examples of this are modularization and versioning, which.NET solved by choosing the assembly, a collection of classes, as the basic deployment unit. Assemblies are equipped with metadata such as version information, unlike Java’s Jar file which lack versioning metadata. This is troublesome for increasingly large applications, which load many libraries. OSGi now provides a solution for this, Sun is busy adding something similar to Java 7.

The Java language keeps on catching up with C#, adding features such as Generics and features such as AutoBoxing, Enumerated types or Annotations. C# now has anonymous expression support, which forms the underpinning of the LINQ technology. LINQ can be thought of a statically typed query language for many different types of data sources, such as XML, relational databases, but also arbitrary object graphs. The Java space, meanwhile, debates language minutiae such as language support for properties and which of four types of anonymous function to include in the language.

The Java space doesn’t really any of the mentioned items, except for the hosting interface, which was added in Java 6, under the name of JSR 223. This is basically just framework to add new language runtimes and initialize and access them in a standardized way.

Jim Hugunin continues with a detailed explanation of how dynamic method dispatch is handled, which makes use of extension methods and other existing CLR systems. The only comparable initiative is JSR 292, which among other things wants to add a new bytecode invokedynamic .This effort was started by Gilad Bracha, who soon after the creation of the JSR, left Sun, and is now not convinced that this project will bring any short term solutions:

Exceto a bizarrice do LINQ, este texto só mostra algo que vem sendo visto diariamente. Provavelmente a JVM e a CLR vão disputar como VMs de linguagens dinâmicas e de DSLs, e tudo mostra uma vantagem técnica para a MSFT. Acordemos.

O Futuro na JAOO

Tuesday, March 20th, 2007

Ótimo painel sobre o futuro da programação no JAOO. Especialmente o comentário do PragDave:

Dave: I’d like to predict that the current stacks of software by 10-15 years are going to be in a much worse legacy and more of a nightmare to maintain. You’re going to have employment forever maintaining this stuff. C++, Java code, C# code, this stuff is very complicated and very brittle with all these class libraries and frameworks. We’re digging ourselves in a really big hole and there will be a lifetime of opportunities for you people to maintain this stuff that you’re creating.

Prepare-se e pense nisso antes de comprar aquela ferramenta mágica ou criar mais um framework que faz a mesma coisa que todos os outros.

Acorda, Maria Bonita…

Tuesday, March 13th, 2007

Lendo a revista Mundo .Net deste mês pensei sobre o estado atual das duas maiores plataformas de desenvolvimento modernas, Java e Microsoft .Net. Infelizmente estou tendendo a creditar em uma coisa: A Microsoft aprendeu, a comunidade Java se acomodou. É impressionante como a MSFT tem investido em ferramentas e plataformas interessantes. A estratégia que pude perceber é mais ou menos assim:

  1. Cria-se uma estrutura fundamental baseada em boas tecnologias e plataformas, geralmente copiadas de casos clássicos de sucesso
  2. Pessoas com nível técnico alto utilizam esta base para criar coisas muito interessantes
  3. Pessoas com nível técnico baixo, grande maioria nas duas plataformas, podem utilizar ferramentas burrotizantes que criam apenas o básico que elas acham que precisam

Dado que as pessoas citadas no item (2) são raridade (eu conheço duas, todos vindos de Java/C++),a estratégia de marketing toda foca no povo do item (3). Para o item (2) (para utilizar um termo MSFT: os Elvis e Einsteins) o marketing é baseado em altos salários e oportunidades muito boas em um mercado saturado de arrastadores de componentes (Morts). Com Java foi exatamente o contrário: a linguagem atingiu o jet-set da computação mas logo se banalizou. Einsteins criaram uma plataforma altamente produtiva e de qualidade impressionante, mas logo Mort caíram em cima, fugindo de Delphi e VB 6.0.

Se o programador mediano Java não tivesse tantos problemas no passado com a Microsoft ele facilmente seria seduzido pela plataforma. Ali tem tudo que ele precisa para fazer seus CRUDs (ou seus grudes…). E se Elvis não tivessem tantos problemas com código proprietário e uma plataforma de um vendedor só eles certamente estariam esmagando cabeças dos programadores Java ao comentar como a plataforma .Net está ficando cada vez mais aberta, cada vez mais flexível, cada vez mais… parecida com sistemas em UNIX.

É sério. Não vou nem citar o MS PowerShell, basta olhar como é feito o deployment em .Net e comparar com um sistema UNIX. Ok, eu sei que é muito mais fácil alguém ter visto um deployment .Net que um UNIX então deixe-me tentar explicar com poucas palavras como geralmente é feito um sistema: cada módulo geralmente é implementado como um programa separado (programa mesmo, tipo uma classe com public static void main(String[])), estes programas conversam entre si utilizando diretivas de IPC. O SO (Linux, HP-UX, Solaris, etc.) controla estes programas (feitos em C/C++, PERL, Python, Ruby, Bash, TCL…).

Se você for esperto já fez uma analogia com um servidor de aplicações J2EE. SIM! Os servidores de aplicação vieram solucionar problemas deste modelo, trazendo um nível de padronização (e racionalidade…) para o processamento de transações distribuídas, segurança, persistência, etc. É para isso que Java EE foi criado, infelizmente as pessoas esqueceram ou não tiveram contato com um ambiente não padronizado e não entendem o que é, por exemplo, um EJB. Ok, mas o problema é que o servidor de aplicações é um mundo a parte, e um mundinho bem fechado.

Tem uns dois anos eu trabalhava para uma empresa líder mundial do setor de sistemas para redes de telefonia celular. Esta empresa possui até hoje uns 90% da base de código em C, rodando em Solaris e outros UNIXes. O sistema principal era exatamente como descrevi: um bando de processos em C que se comunicavam via pipes, filas de arquivos e memória compartilhada. parece uma zona, não? Nada de JMS para mensageria, nada de JAAS para segurança, nada de nada.

Pois a grande vantagem deste sistema não era a velocidade, como defendiam os xiitas locais. A vantagem era a flexibilidade. Quando uma correção era implementada o meu colega de baia enviava para o cliente um patch contendo apenas os processos modificados. Quando eu corrigia uma linha de código tinha que mandar um EAR de 10 megabytes. O primeiro nível de suporte era capaz de fazer scripts em PERL e Bash que corrigiam problemas quando aconteciam e automatizavam tarefas para o programa em C. para o programa em java só o próximo release implementaria a mais boba das tarefas, ou uma famosa dedada no banco de dados (um script SQL).

Claro que a culpa é dos programadores (não me excluo) que não se prepararam para sistemas abertos e extensíveis (anos depois eu consegui fazer alguns progressos nesta área e sumarizei em uma palestra), mas o maior problema é na forma que um Application Server é fechado, lacrado. Mesmo os servidores mais modernos ainda contam com abertura precária se comparados aos bons e velhos sistemas UNIX dos anos 70/80/90.

E neste ponto a Microsoft vai na frente, por incrível que pareça. Sua plataforma está baseada em Camadas que são unidas pelo SO, é como se a pessoa pudesse implementar um sistema UNIX utilizando um framework de workflow, persistência, apresentação, comunicação remota, transações e segurança unificado, não importa qual linguagem (e .Net é multilinguagem desde sempre).

Não, eu não estou falando para você migrar para .Net. O que eu estou dizendo é que Java está trilhando caminhos muito perigosos, como desenvolvedores nós temos que ficar de olho. Cuidado com ferramentas milagrosas e,principalmente, cuidado com caixas fechadas (ainda que sejam Open-Source).

E os Einsteins? Eles brincaram com Java mas voltaram para LISP.

Eric Evans no infoQ

Thursday, January 4th, 2007

Ok, notícia velha, me critiquem por ser lerdo, mas não posso deixar de comentar esta excelente entrevista do Eric Evans no infoQ.

The long-term trend is toward applying software to more and more complex problems deeper and deeper into the heart of these businesses. It seems to me this trend was interrupted for a few years, as the web burst upon us. Attention was diverted away from rich logic and deep solutions, because there was so much value in just getting data onto the web, along with very simple behavior. There was a lot of that to do, and just doing simple things on the web was difficult for a while, so that absorbed all the development effort.

But now that basic level of web usage has largely been assimilated, and projects are starting to get more ambitious again about business logic.

Com outro trecho mais adiante…

Combine that with the imperative to produce Web UIs mediated by http and html (which were not designed for that purpose) using quite primitive, first-generation tools. During that period, creating and maintaining a decent UI became so difficult that little attention was left for design of complex internal functionality. Ironically, at the very moment that object technology took over, sophisticated modeling and design took a heavy hit.

Sintetizam as desculpas (esfarrapadas) para se produzir aplicações baseadas em objetos burros nos últimos anos.

For example, SOA, when it is used well, provides us a very useful way of isolating the domain.

Este é outro ponto interessante. Muitas vezes vemos SOA sendo utilizado como desculpa para modelos de objetos burros e fracos, ou até mesmo para uma volta ao Dicionário de Dados. Serviços não trocam, ainda, objetos inteligentes e sim estruturas de dados mas dentro do serviço nós temos um sistema OO e, como tal, deve ser construído utilizando objetos!

E lembrem-se: objetos são dados e comportamento num mesmo conceito.

But back when the J2EE frameworks first came out, it utterly buried that basic expressiveness under mountains of framework code. Following the early conventions (such as EJB home, get/set prefixed accessors for all variables, etc.) produced terrible objects.

Isso eu comentei bastante no artigo sobre VO/BO.

Rails has generated a lot of excitement because it finally seems to make creation of Web UIs as easy as UIs were back in the early 1990s, before the Web. Right now, this capability has mostly been applied to building some of the vast number of Web applications which don’t have much domain richness behind them, since even these have been painfully difficult in the past. But my hope is that, as the UI implementation part of the problem is reduced, that people will see this as an opportunity to focus more of their attention on the domain. If Ruby usage ever starts going in that direction, I think it could provide an excellent platform for DDD. (A few infrastructure pieces would probably have to be filled in.)

Este trecho toca na minha crítica #1 com Rails: domínios fracos baseados em Bancos de Dados. A linguagem Ruby é tão cheia de vantagens que a limitação imposta pelo modelo CRUD do Rails me irrita profundamente. Ok, você não precisa ter um modelo fraco em Rails, mas você também não precisa ter um modelo fraco ao usar EJB 2.1, VB 6 ou Delphi e isso nunca evitou este problema.

More out on the cutting-edge are the efforts in the area of domain-specific languages (DSLs), which I have long believed could be the next big step for DDD. To date, we still don’t have a tool that really gives us what we need. But people are experimenting more than ever in this area, and that makes me hopeful.

Outro ponto muito bom. DSLs são iminentes mas as ferramentas simplesmente ainda não chegaram lá. O grande perigo é que o conceito está se tornando popular mas não existem ferramentas. Algo semelhante aconteceu com OOP, as linguagens eram procedurais mas todo mundo falava em OO, gerando a célebre consideração sobre C++ que eu traduzo mal e porcamente abaixo:

C++ é como sexo para adolescentes

  • Está na sua cabeça o tempo todo.
  • Todo mundo fala disso o tempo todo.
  • Todo mundo acha que todo mundo está fazendo o tempo todo.
  • Quase ninguém está fazendo de fato.
  • Os poucos que fazem:
    • estão fazendo mal e porcamente.
    • têm certeza que da próxima farão melhor.
    • não fazem com segurança.
  • Ainda assim todo mundo fala sobre como estão tendo sucesso com isso, ainda que uns poucos tiveram qualquer nível de sucesso

Bom, não percam!

Porque C++ tem friend e struct?

Wednesday, May 24th, 2006

O Zé pergunta no blog dele e como não está funcionando no momento eu respondo aqui, espero que o trackback esteja habilitado por lá…

strutcs: Basicamente para manter compatibilidade com C. Tem que ser levado em consideração que C++ é uma linguagem multi-paradigma, é OO e Procedural, e numa linguagem procedural você vai precisar normalmente de estruturas de dados customizadas para serem manipuladas por funções.

friend: Isso é chamado de selective export, mas em C++ não é muito bem implementado. Basicamente o objeto parece uma coisa para um e outra para outro, depende do ponto de vista. Em Java podemos simular isso fazendo um objeto implementar múltiplas interfaces e fazer com que outros objetos conheçam-o por uma delas apenas.