Fontes… De informação

Utilizo a um bom tempo algumas fontes de informação e em especial a que mais gosto é a do Linux Weekley News.
Hoje, infelizmente, eu não estou mais assinando como fazia no passado.
Mas como a característica daquele site é ser open, uma reportagem disponível para assinantes fica, depois de um certo tempo, liberada para leitura para os “pobres”.
Hoje saiu uma chamada para um assunto que tenho bastante interesse e já falei algumas vezes aqui: orientação a objetos utilizando linguagens sem suporte formal à técnica.
Esta abordagem foi feita no gtk e diversos projetos a utilizam.
Sempre me pergunto, já sabendo de antemão a resposta, o por quê de assim ser feito? As respostas podem variar, mas a minha predileta é a que atribui à melhoria de performance. Mas, existe outra que me estimula explorar melhor a questão: organização e reutilização de código (e projetos).
Sabia que o nosso venerado linux faz esta abordagem, visando performance, mas a organização, pelo menos para quem não tem familiaridade com projetos de envergaduras maiores, é um tanto caótica.
Enfim, lançaram parte 1 deste artigo: Object-oriented design patterns in kernel – bloqueado para não assinantes, até o dia 09/06/11.
Eu, que já anotei na minha agenda, começo a ler na quinta.
Juntar três assuntos – kernel, oo e design patterns – e aprender mais sobre o “core” de um projeto destes? Quem não quer?!
Enquanto isto os “peladeiros” salivam, na iminência do lançamento da “oitava porcavilha” do universo.

Uma prova de performance

Sempre está sendo dito e defendido que perfomance é fundamental. Esta performance depende de outros fatores além da otimização do código. Um deles é a escolha da tecnologia e da linguagem de programação.

Estou analisando o código do Cos – link que indiquei no último post, e ao compilar o primeiro dos programas fiquei espantado com a diferença de performance entre C e C++.

O C neste caso parece ser cerca de 5x (no meu teste) mais rápido do que C++.

/* Em C */
AB    : dynamic_cast<A*>(b) = 3218961676, iter = 62500000/sec
DCABBA: dynamic_cast<A*>(b) = 3218961600, iter = 21739130/sec
DCABBA: dynamic_cast<C*>(c) = 3218961556, iter = 21739130/sec

/* Em C++ */
AB    : dynamic_cast<A*>(b) = 3214284680, iter = 12048192/sec
DCABBA: dynamic_cast<A*>(b) = 3214284604, iter = 6622516/sec
DCABBA: dynamic_cast<C*>(b) = 3214284560, iter = 3267973/sec

O link dos fontes pode ser baixado daqui e faz uma demonstração de implementação de padrões orientados à objetos com o C.

Como dito pelo autor:

C++ Object Model is a long paper (see object_model.html) started years ago which I unfortunately never finished (about 25% achieved), but is enough to understand the overall. It comes with a complete example in C (see cmd_c.sh) and C++ (see cmd_cpp.sh) which describes one way to implement the C++ object model (i.e. the g++’s object model). It is addressed to advanced (and motivated ;-) C and C++ programmers who have some interest in the C++ object model, so I put it here for curiosity. It may give you some hints about the implementation complexity corresponding to the management of dynamic types within constructors and destructors (i.e. intermediate vtbl) and covariant and contravariant types in the presence of multiple and virtual inheritance (i.e. thunks). I found interesting that my naive implementation of dynamic_cast is about x3 faster than the dynamic_cast provided by g++ ;-)

Nota adicional: o compilador utilizado é o gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) e o programa foi rodado num Core 2/2.2 GHz/3Gb Ram

E os objetos?

Onde estão os objetos em C ?

Sabemos que C é uma linguagem bem versátil e que permitiu ainda permite a criação de ferramentas muito úteis em todos os setores de tecnologia.

Tenho visto estatísticas e apesar de não confiar muito nelas, vemos a ascensão de linguagens que oferecem suporte completo ao paradigma da orientação a objetos.

Há crescimento do Java, Python, Ruby, Php, C++, .Net, etc. Surgimento de frameworks escritos em todo o tipo de script que se possa imaginar e eu me pergunto: qual o objetivo desta profusão de linguagens?

Esta pergunta fica dançando na minha cabeça há tempos e a melhor resposta que pude resumir é: porque existem humanos e tecnologia barata à disposição. Sendo humanos, todos querem ter o seu minuto de janela neste universo. Portanto, utilizam a tecnologia barata à disposição.

O resultado desta salada é um conjunto de bobagens linguagens umangleltra especializadas que distorcem os conceitos matemáticos existentes por detrás da Ciência da Computação, e aplicam camadas de “gírias” sobre o bom e velho latim.

Se filtrarmos estas linguagens de seus dialetos encontraremos as raízes no trabalho de alguns cientistas que trabalharam durante a primeira metade do século XX, resolvendo estes problemas, assim como resolveram outros em física, matemática, biologia, etc. Criaram soluções, demonstraram possibilidades, levantaram hipóteses e teorizaram bastante. No fim dos anos 60, início dos 70, a tecnocracia existente resolveu reaver o dinheiro empregado nas pesquisas feitas por aqueles cientistas e começaram a empacotar “produtos” comercializáveis. Daí as primeiras gerações de Unix, Computadores Pessoais, Suítes de Escritórios, Bancos de Dados, enfim tudo aquilo que utilizamos hoje só que numa versão “preto e branco” ainda não refinada.

Passados vinte anos, começaram a reinventar a roda e “travestir” a matemática, feita nos quadros negros com giz branco, em janelas coloridas manipuláveis com mouse. A peça principal que antes existia – o Professor – foi substituído por uma entidade onipresente, onipotente e onisciente: o Google!  Ótimo, agora todos são cientistas, cineastas, fotógrafos, jornalistas, radialistas e querem deixar a sua marca face no “book” da tecnologia.

E onde está o foco deste artigo, MaRZ?

Voltando ao ponto central. Eu busco ver isto tudo como evolução e o preço que pagamos por ela é o da assimilação. Trata-se de um processo de digestão. Devemos “comer” toda a informação, mastigar bem, digerir e …

Existem certos sistemas operacionais, linguagens e “tablets” que devem ter o mesmo destino do subproduto de uma digestão.

No processo digestivo, entretanto, absorvemos certos nutrientes que deram tempero e são saudáveis. Entre eles eu considero o paradigma da orientação a objetos e alguns padrões de desenvolvimento. O padrão MVC é um que eu realmente acho interessante.

Daí surge um problema que me atormenta há anos. Como utilizar OOP em projetos simples e rápidos sem abrir mão das raízes matemáticas de linguagens funcionais?

Em primeiro lugar, devemos entender o que é orientação a objetos e isto é um assunto extenso, que não consigo resumir e, confesso, não sou um expoente deste conhecimento. Somente sei que aplico alguns conceitos e gostaria de evoluir mais com isto.

Só para registrar, dizem que uma linguagem deve possuir meios de implementar a tríade – Encapsulamento, Polimorfismo e Herança – para ser considerada uma linguagem orientada à objetos “de facto”. Há controvérsias, pois penso que estes trẽs itens são conceitos e não artifícios. Podem existir nestas linguagens certos artifícios que facilitem a implementação do conceito. Mas como todo conceito acaba sendo subjetivo, surgem as guerras sobre qual a linguagem que se aplica melhor ao conceito. E assim filosofia fluirá nos guardanapos ad eternum, no seu passo de automato: hipótese, síntese e antítese.

Recentemente, num projeto pequeno que estou fazendo, senti necessidade de aplicar o MVC para agilizar o processo. Mas somente fiz isto após definir bem algumas funções de chamadas às bibliotecas pré-existentes, testes de regressão e alguma otimização. Mas ficou – e ainda está – faltando uma “cola” que una de forma simples o meu conjunto de código já existente.

Neste ponto é que percebo onde a linguagem C é ineficiente, até mesmo frustrante. Falta alguma coisa!

  • Usar C++ ? Não, isto muda o conceito de “pequeno” para grande e o meu “pequeno projeto” vira um elefante branco descontrolado.
  • Criar extensões em linguagens que já contenham o paradigma? Não, isto cria “pontos de dilatação” muito sensíveis. Teria que se lidar não com uma, mas duas ou mais linguagens e, convenhamos, dar manutenção nisto é muito desagradável.
  • Usar um Framework? Não. Deixo de aprender uma linguagem e passo a ter que ler manual de um produto. Confesso que não gosto de ler manual, principalmente sabendo que o produto vai ficar obsoleto em questão de meses.

A opção menos áspera, estou investigando ainda, me parece ser a de aplicar os conceitos de OOP, utilizando-se os recursos que se tem em mãos. Este conceito começa a existir na imaginação e não se impõe ao código, mas trabalha junto com ele.

Dou um exemplo disto usando o Lego.

Consguimos fazer uma esfera com ele, mas para ficar perfeita o quão queira, a peça, no caso a bola, teria que crescer mais e mais. Quanto maior, mais perfeita, mas sempre seria composta de blocos retangulares.

O ponto chave, na minha opinião é: você deve enxergar uma bola, mesmo na primeira peça a ser montada. Isto é muito fácil para uma criança pois ela, sendo dotada de muita imaginação, não possui os limites de realidade impostos aos adultos. E, para um adulto, isto é muito complexo pois gera grandes desconfortos: quantas peças eu tenho para montar esta bola? Quão redonda eu necessito e posso pagar por ela? Será que vai agradar? Eu poderia ter um Lego com peças especializadas ou mesmo menores?

Nesta abstração, enxergar a bola na primeira peça que é a parte díficil.

Na prática, ainda estou estudando este assunto mas encontrei alguma luz no fim do túnel aqui: Object-oriented programming in C.

No mais, o resto é atitude pragmática e desprendimento de pré-conceitos.

  • Não sou matemático, mas gosto e uso matemática no meu ofício
  • Não sou carpinteiro, mas gosto de construir objetos, além de somente conceitos e idéias
  • Gosto de C e não quero chafurdar no pântano de tecnologias sem sentido “só porque estão aí” ou acadêmicas demais
  • Não sou gerente, mas gosto de produtividade e medir a quantas anda a minha

{}’s

MaRZ