04
100% pure Object-Oriented: The Fallacy
on September 04, 2007

Essa é uma das afirmações mais falaciosas quando queremos criar uma Guerra Religiosa: “Sua linguagem não é 100% orientada-a-objetos, portanto, logo, por conseguinte, a minha é mais forte.” Quantas vezes já não ouvimos isso? Acho que desde que Simula (a primeira orientada a objetos) ou C with Classes (a primeira extenção de classes para C) foram lançados, décadas atrás, ouvimos a mesma coisa.
Ela parte de dois princípios argumentativos igualmente falaciosos:
- “Toda boa linguagem é orientada a objetos.”
- “A quantidade de funcionalidades OO que uma linguagem suporta é diretamente proporcial à sua capacidade.”
A primeira não pode ser considerada um axioma, porque possui muitos falsos positivos. A segunda é derivada da primeira e não podemos provar uma negativa baseada em outra negativa. Foi o que eu expliquei no artigo Inimigos da Razão. Aliás, nenhum dos criadores de linguagens costuma usar esse tipo de afirmação.
Basta lembrar que orientação a objetos é apenas uma de dezenas de características que moldam uma linguagem e nenhuma implementa 100% delas (porque não seria prático). No wikipedia há mais detalhes mas só como exemplos. Temos linguagens orientadas a aspectos (Java, Common Lisp), linguagens compiláveis (Ada, Algol, C), linguagens concorrentes – que enviam mensagens (Concurrent Pascal, Clik, E, Erlang), linguagens orientadas a dados (SQL, ABAP, Clipper), linguagens declarativas (Prolog), linguagens funcionais (Lisp, F#). E por aí vai. Isso sem contar as que tem tipagem forte/fraca ou estática/dinâmica.
12 anos atrás houve muita discussão se Java é ou não 100% orientada a objetos. O problema: não existe uma definição oficial para isso. Não existe um paper na ISO, no ECMA, nenhuma RFC, IEEE ou qualquer coisa que categoricamente defina “isto é, sem sombra de dúvida 100% O.O., ou 50% O.O.”. O que se considera – por consenso público – uma linguagem O.O?
- suporte encapsulamento
- suporte herança
- suporte polimorfismo
- faça chamadas através do envio de mensagens entre objetos
- todos os tipos básicos são objetos
Alguns dirão que Java suporta herança simples, mas como não suporta herança múltipla, não é O.O. C++ suporta múltipla herança. Outros vão contra-argumentar que de fato Java suporta múltipla-herança de interfaces. Alguns dirão que Java tem tipos primitivos e isso não é O.O. C++ também tem, portanto também não é O.O. Outros vão atacar dizendo que só deveria haver tipos básicos como objetos. Ou seja, tipos primitivos com a ‘gambiarra’ de classes Wrappers não vale. E isso não tem fim, podemos passar anos discutindo isso (oras, já passamos anos discutindo isso!)
Vejamos uma definição (não oficial) na Wikipedia : “Linguagens chamadas ‘puro’ O.O., porque tudo neles são tratados consistentemente como um objeto, de primitivas como caracteres e pontuações, subindo o caminho todo até classes, protótipos, blocos, módulos, etc. Foram desenhados especificamente para facilitar, até mesmo reforçar, métodos O.O.. Exemplos: Smalltalk, Eiffel, Ruby.”
Como esquecer do venerado Bertrand Meyer e seu Eiffel), inspiração para todas as linguagens modernas com aspectos de objetos principalmente por uma funcionalidade que quase nenhum linguagem tem: assertions (Design by Contract), algo mais forte do que tipagem estática ou herança de interface.
Nessa definição de O.O., Java e Python não se encaixam porque elas preservam alguma natureza procedural. Esta tabela de comparação, entre Eiffel, C++, Java e Smalltalk levaria muitos a crer que Eiffel é, de longe, a melhor linguagem. Fica obscuro porque ela não é a mais popular.
O máximo que podemos efetivamente afirmar sobre uma linguagem é se ela é Turing Complete ou não. C++, Java, Ruby, Smalltalk, Python são todas Turing Complete. SQL não é. Uma linguagem muito promissora, por exemplo, é Scala. ela é uma linguagem orientada a objetos (no sentido que todo valor é um objeto), funcional (no sentido de que toda função é um valor), com tipagem forte e estática, que roda sobre a JVM (novamente, uma das melhores VMs já feitas). Ruby é uma linguagem O.O., com aspectos funcionais, tipagem forte e dinâmica, e interpretada. Smalltalk é O.O., sem aspectos funcionais relevantes, mas com tipagem forte e dinâmica e compilada para uma VM. Visual Basic é uma linguagem procedura, com aspectos de O.O., tipagem fraca e dinâmica e pré-compilada para um interpretador.
No final, a linguagem/plataforma que melhor levar seu projeto até o final é a vencedora (levar até o final e sem deixar mortos no meio do caminho, de preferência). Todo projeto nasce diferente, tem requerimentos diferentes (performance, reliability, maintainability, security, size, scalability, manageability, learning curve, industry support, market support, etc). Nunca pense: “só pode haver um”. Esse pensamento Highlander leva as pessoas a enxergar todo problema como pregos, pois a única ferramenta que ele conhece é um martelo (Hammer and Nail problem). Ou alguém pode querer inventar o framework para bater todos os frameworks, a linguagem para bater todas as linguagens. Apenas implementar todas as funcionalidades listadas acima não garante um bom produto. Acaba-se no famoso problema de se criar uma solução procurando por um problema.
Por isso fica minha recomendação – constante, persistente e insistente em todo artigo: não se limitem, aprender mais e mais é o que nos torna melhores, em qualquer coisa. É o que chamamos de Cultura (que vem de “cultivar”).





Esqueci de dizer: Ruby é – pela definição apresentada – 100% orientada a objetos. Tão O.O. quanto a próxima.
Alan Kay tem uma visão interessante sobre esta questão de o quê uma linguagem tem que ter para ser considerada OO:
“OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I’m not aware of them.”
Ruby suporta! Aliás, só entendi o que Kay queria dizer quando vi como Ruby funciona…
Excelente lembrete, o e-mail completo de Alan Kay sobre isso é este. E você está certo. Ruby suporta tudo isso. Raw Block, no seu blog fala sobre Erlang e diz: “Looking for OOP in Erlang is like looking for religious icons in a cheese sandwich”.
Por curiosidade, recomendo esta excelente entrevista com o próprio Alan Kay.
Ruby falha em um critério básico no texto acima, citado do Alan Kay. Exercício para o leitor. :-)
“com tipagem forte e estática, que roda sobre a JVM (novamente, uma das melhores JVMs já feitas)”
Não seria uma das melhores VMs feitas, ou alguma outra coisa? :D Abraço!
“local retention and protection and hiding of state-process”: nope (você pode acessar o que quiser via meta-programação, seja elementos private/protected ou não)
É algo que será revisado no YARV, mas é o mesmo argumento de sempre: o programador é o responsável pelo que está fazendo. Se ele “quis” acessar estados privados, fazer o que?
Aliás, só porque o Alan Kay citou uma opinião pessoal, isso é irrelevante para a questão porque, como eu disse antes: não existe definição formal – como um IEEE – sobre o que é ser 100% OOP.
Citação por citação acaba-se achando coisas como essa: I always thought Smalltalk would beat Java, I just didn’t know it would be called ‘Ruby’ when it did. – Kent Beck.
Quem lê isso ingenuamente pode acreditar que Ruby é melhor do que Smalltalk só porque o Kent Beck disse. Vai se saber as circunstâncias dessa afirmação?
Se ruby falha no teste do Alan Kay Smalltalk também: “Smalltalk will even let you get at private variables using reflection” http://wiki.cs.uiuc.edu/VisualWorks/Smalltalk+and+private+and+public+methods
Existem diversas formas de se usar contratos em python, não é algo já vem pronto na linguagem, mas que é facilmente implementável. Existem módulos já prontos pra isso, mas que não são builtin.
Uma dúvida que eu tenho, apesar de conhecer pouco ambas as linguagens é : “O que Python tem de procedural que Ruby não tem?”
Lembro que certa vez estudando Ruby quis tratar um método como objeto de forma semelhante ao que conhecia em python e não consegui. Deve ter sido falha minha, mas também não sei dizer se método em Ruby são objetos também e que também possam ser manipulados como tal.
Não quero parecer nenhum fanboy, não é isso, acho python e ruby muito interessante e queria apenas aprender um pouco mais.
Valeu Akita!
Essa é a velha discussão: Python é ou não é orientado a objetos?
Rubistas precisam também parar de pegar no pé do Python. Até eu já devo ter cometido essa gafe.
A maior parte da crítica vem da era pré 2.2 do Python, quando não era possível realizar sub-classing de built-in types.
Muita gente também confunde o recurso de open classes do Ruby (que não existe em Python, nem em Java). Mas isso é mais um bônus e também não desqualifica as outras linguagens.
Sobre funções, em Python eu sei que elas são first-class citizens, como dizemos. Em Ruby temos blocks. A idéia é deferred functions. Ambas tem algo parecido.
Python é uma excelente linguagem. Guido Von Rossum é um cara genial. Algumas coisas certamente poderia mudar um pouquinho (como o monte de ‘self’ espalhados pra lá e pra cá) ... mas isso sou eu. What do I know? :-)
Akita, sinto muito mas não é isso. Tem a ver com o messaging e especialmente com a palavra only.
O fato de não haver uma definição forma por padrões não implica em absolutamente nada, por sinal. Seria corporativismo presumir que é padronizar um conceito. Estou até vendo as patentes.
O fato é que, independente de coisas como “a minha grama é melhor que a sua”, existe uma definição simples e sujeito à Navalha de Occam para uma linguagem puramente orientada a objetos: uma linguagem que só usa objetos. Poucas linguagens passam nesse crivo e isso responde à questão também.
Informalmente, eu uso “puramente orientado a objetos” como uma especificação. Tanto é que nos meus cursos de Rails e no meu tutorial digo que o Ruby é puramente orientado a objetos. E na palestra frisei que o Rails e não o Ruby não usa objetos corretamente.
Tudo isso não quer em absoluto dizer que uma linguagem seja melhor que a outra. Por outro lado, você cai na mesma falácia que professa negar ao dizer que o máximo que se pode dizer sobre uma linguagem é que a mesma é Turing-complete. É óbvio, até mesmo pela sua defesa apaixonado do Ruby, que o mesmo difere em algo de outrasl inguagens onde abstrações são menos evidentes.
Em última instância, a aplicação ao contrário do simples conceituamento pode elevar uma linguagem semanticamente a um patamar superior. Se isso não fosse verdade, nenhuma das linguagens modernas teria surgido—e não, não estou falando das linguagens surgidas dos anos 90 para cá.
Por fim, há sempre uma prova prática: redefinir a linguagem sem sair da mesma. Esse é um feito que, Turing-complete ou não, raríssimas linguagens pode fazer.
Vamos lá, adoro respostas compridas :-)
Estranho: para que uma linguagem tenha late binding, implica haver message passing. Portanto, se 1 está errado, 3 também está. Mas felizmente não é este o caso já que Ruby, assim como Smalltalk, é baseado em message passing, não em method calls. Message passing, também chamado de Delayed binding. Claro, Smalltalk é “mais” baseado em messages do que Ruby. Na prática não há nenhum diferença crucial nisso.
O fato de não haver uma definição formal é que discussões como esta poderiam ser economizadas. Imagine se não houvesse a IEEE 754 e estivéssemos até hoje discutindo qual a melhor maneira de representar um ponto flutuante double precision de 64-bits. Iríamos discutir madrugada a dentro. Ou se não houvesse a Unicode Consortium e ainda estivéssmos discutindo qual a melhor maneira de armazenar caracteres cirílicos. Uma definição formal de Orientação a Objetos viria a calhar, apesar que talvez exista um motivo para ela não existir: porque não é relevante. A indústria não viu nenhuma vantagem em comparar uma linguagem uni-dimensionalmente por ela ser “mais” ou “menos” orientada-a-objetos. O pessoal de marketing ainda gosta disso, mas tecnicamente não é importante.
Sobre a Navalha de Occam, chegamos a um assunto favorito :-) “Todas as coisas sendo iguais, a solução mais simples tende a ser a correta”. Vejamos as premissas para a explicação “linguagem puramente orientada a objetos”_:
Beware! A Navalha de Occam pode ser erroneamente ser utilizada para cair na lógica circular (petitio principii), literalmente a conclusão do argumento é implícita ou explicitamente assumida nas premisas. Ou seja, “uma linguagem puramente OO é uma linguagem que só usa objetos”, por outro lado, “uma linguagem que só usa objetos é uma linguagem puramente OO”. Portanto, caímos numa retórica. E ainda recai na conclusão incerta: “uma boa linguagem é totalmente orientada a objetos”, o que não é verdade.
Minha “bronca” com a insistência em ser “puramente” OO é porque apenas dizer “a linguagem é puramente OO” parece implicar em alguma vantagem. Porém: qual a vantagem prática de ser “puramente OO”? Qual a evidência empírica de que isso poderia ser postulado? Talvez exista, eu não sei, mas ainda não fui apresentado a uma.
Ser “baseado em orientação a objetos”, isso sim tem vantagens práticas: poder encapsular funcionalidades, herdar de outras classes, enviar mensagens para realizar late binding. Tudo isso é vantajoso. Assim como são coisas não-OO como classes abertas (mixins) e até mesmo tipos primitivos não-objetos em muitas circunstâncias.
Vamos lá: eu defendo “apaixonadamente o Ruby”, bom, não são por motivos acadêmicos, garanto :-) E nem é tão “apaixonado” assim. Paixão implica em realizar atos irracionais, o que não é o caso: eu não deixei de gostar nem de usar Java nem C# – e não recomendo ninguém a largar uma pela outra! O motivo de utilizar Ruby é justamente pelo enfoque pragmático não-puramente-acadêmico (no-nonsense se preferir). Matz não é um acadêmico. DHH está longe de ser um. Felizmente houveram grandes acadêmicos no passado que compilaram diversas experiências e, em não se ignorando o que já foi aprendido, tanto Matz quanto DHH pegaram as boas lições e aplicaram num pacote simples e prático. A força do Ruby ou Rails é justamente essa: jogar fora o que não é prático e aplicar o que é. Graças a isso, muitos outros frameworks estão seguindo essa linha.
Outra coisa: não há nenhum problema em se usar MVC (tanto a definição original quanto o MVC da Sun – o mais comumente referido como MVC). Novamente, HTTP não é o protocolo ideal para stateful. Já foi testado, já foi experimentado. Em pequenos aplicativos não faz diferença, em grandes faz muita diferença – e sai caro. Um exemplo de protocolo de rede para realizar RPC num ambiente componentizado stateful? X11 protocol. MVC para Web e MVC para Desktop não são iguais.
Eu sou um grande defensor da pesquisa e da experimentação. Séculos de história e desenvolvimento da ciência já demonstraram isso, e mais rápido ainda na tecnologia. Também demonstraram que não podemos nos apegar a apenas uma tecnologia. Se ela não se encaixar mais nesta época do espaço e do tempo, deve ser descartada. Um exemplo que eu gosto muito de desenvolvimento acadêmico que se tornou um sucesso comercial viável dentro de seu nicho: Lua, criado na PUC-Rio, uma linguagem multi-paradigma cuja principal característica é ser leve (150kb de interpretador), que é algo importantíssimo para o mercado de embedded systems. Ser leve foi o fator crucial, não o “defeito” de ser multi-paradigma. Por isso que uma análise uni-dimensional não é razoável, principalmente se “escondermos” os defeitos reais. DHH ouviu bastante na orelha depois da polêmica do Twitter – apesar de não ter torcido o braço, já que o slogan de “máquinas é mais barato do que tempo de desenvolvedores” surgiu com o Rails. Felizmente muita gente já achou algumas soluções para isso – embora nenhuma drástica ainda.
“Não se pode esperar por coisas diferentes fazendo sempre a mesma coisa.” Esse é meu lema. Não significa que precisamos olhar para qualquer coisa diferente. Também significa que falar bem de uma coisa não deve implicar falar puxar o tapete da outra. Querer trazer alguma virtude a um tentando implicar num “defeito subjetivo” de outro não é um argumento técnico razoável. Esse é o principal problema e que não colabora em nada para a evolução de nenhuma das opções.
Avi Bryant, por outro lado, é totalmente o contrário. Não só ele palestrou na RailsConf 2007 como ele gosta de Ruby, disse isso na palestra (e no excelente podcast de Geoffrey), considera que Seaside poderia ser implementado em Ruby e que Ruby poderia rodar no Strongtalk VM, já que “Ruby é praticamente Smalltalk”, nas suas próprias palavras. Ele considera que Smalltalk não precisa de mais marketing e que não sente falta de trazer a tecnologia para mainstream: pessoal de Smalltalk prefere ficar nos nichos, onde seu trabalho é valorizado justamente porque não tem mais gente para concorrer (isso está no podcast).
Avi veio de Ruby. Não quer dizer que “ah, Avi trocou Ruby porque Smalltalk é melhor.” Por outro lado pessoas como Josh Susser saíram de Smalltalk para ir para Ruby. Isso implica alguma coisa? Nada: escolha pessoal que não deve servir de resposta a ninguém. Cada um deve experimentar e escolher a plataforma em que se sente mais confortável, livre de mitos.
Eu já não gosto tanto de respostas compridas, mas vamos lá:
Se 1 está errado, 3 também está. Isso é óbvio, mas você disse que 2 era o problema. Portanto, o que eu disse continua valendo e você estava errado. Duas falácias em uma linha só sua: conclusão fora das premissas e desvio de argumentação. O perigo de tirotear falácias para cima e para baixa é justamente esse: a não ser que você construa seu argumento formalmente, você comete outro tanto.
Sobre a questão da definição formal, ela existe para padrões de implementação e não para conceitos. Representação de ponto flutuante e a questão do Unicode são exemplos claros disso, mas nenhum dos dois é padronizado sobre o conceito de número decimais ou caracteres em si. É possível padronizar linguagem, obviamente, mas novamente é uma questão de implementação. Preciso citar a falácia no argumento?
Sobre o petitio principii, mais uma vez você comete múltiplas falácias. Primeiro, por aplicar incorretamente o mesmo ao declarar uma conclusão que é a própria permissa. Essa falácia implica em dependência e não em simplesmente reformular a frase como você fez, invertendo a ordem das palavras. A questão toda está no uso de puramente que aqui se torna uma questão de semântica de idioma e não de conceitos externos. “Puramente” significa “sem misturas”, “sem alterações”. É óbvio que no contexto em questão, a implicação é essa. Assim Smalltalk é pura porque você pode construir a linguagem toda somente com uso de objetos e extendê-la da mesma forma sem necessidade de construtos adicionais. Há outra falácia aqui no seu argumento: correlação implica em causa.
Existem outras linguagens igualmente puras em suas áreas e isso não significa que híbridos como o Ruby sejam piores. Isso não implica, ao contrário que você disse, que uma boa linguagem é totalmente orientada a objetos. Quando você diz que implica, você também cai em mais uma falácia: generalizações apressadas.
Como é claro da minha resposta acima, eu não acredito que pura orientação a objetos seja um motivo em si, mas um bom fator para ajudar na escolha de uma linguagem. Você pergunta: onde está a evidência empírica. Eu respondo: em 30 anos de indústria. Por que é que 70% dos projetos em Java falham? Por que há a necessidade de AOP e centenas de outras alterações na linguagem? Por que o Groovy existe? Por que Ruby está ganhando as mentes e corações dos desenvolvedores? Puro hype? Claro que não, por que Java teve mais hype que qualquer outra linguagem na história. Determinados elementos de uma linguagem a tornam, sim, melhor que outras. Ruby usa DSL para atingir maiores abstrações. Smalltalk não precisa de DSL porque é idiomaticamente uma DSL. E todas essas coisas não implicam que ela é a melhor linguagem para tudo e nem que é para muitas coisas por ser OO.
Não entendi a referência ao MVC, já que não falei nada sobre isso.
Sobre a questão de stateful, se não funcionasse sobre HTTP você não usaria sessões (uma alternativa pobre para o que a Seaside faz naturalmente sobre o mesmo protocolo). Mais uma vez você tira conclusões apressadas, sinto em dizer. De certa forma, você pode considerar HTTP um protocolo stateful porque é construído sobre TCP que é certamente um protocolo stateful. Só o é de uma maneira diferente. Colocar statefulness em um protocolo é somente uma questão de entender como isso pode ser feito. Seaside faz com suas URLs, Rails faz com sessões. Qual é melhor? Depende do que você precisa.
O resto da sua argumentação é um desvio. Se você estava respondendo ao meu comentário, respondeu por um monte de afirmações que não fiz, como não gostar de experimentação, achar que Smalltalk deve substituir Ruby, achar que se deve usar só uma linguagem, etc. Se estava respondendo a outros, não passou de “ignoration elenchi”.
Mas estou gostando de ver seu interesse repentido em Smalltalk. Isso significa que minha palestra conseguiu seu objetivo: fomentar experimentação e discussão.
“late biding implica em message passing”...
Sei não, estava lendo um livro de Lisp esses dias atrás e o CLOS não é feito por message passing (até onde entendi), mas a linguagem é late binding.
Tá certo isso?
Ronie, do jeito que o Akita expressou não. Mas o converso é verdade dada a natureza da implementação OOP (dentro de limitações de prática e velocidade). Por isso eu coloquei 1 e 3 e não 3 e 1.
Bom, então agora precisamos explicar. Lá em cima, o Emerson citou Alan Kay, que por sua vez estava definindo OOP:
OOP “to me” means (enfatizando o “para mim”):
Você disse “Ruby falha em um critério básico no texto acima”.
Eu disse que é: “local retention and protection and hiding of state-process”: você pode acessar o que quiser via meta-programação, seja elementos private/protected ou não).
Depois você disse: “Se 1 está errado, 3 também está. Isso é óbvio, mas você disse que 2 era o problema. Portanto, o que eu disse continua valendo e você estava errado.”
Ficou confuso: se você já tivesse dito antes: “Ruby falha nos 3 critérios” vá lá, mas dizer que falha em ‘um’ e depois dizer que na verdade falha em dois, fica difícil :-) “É óbvio”, não é uma boa resposta. Mas vamos deixar o benefício da dúvida e dizer que “falha em um critério básico” queria dizer “falha em um critério básico e no outro, sub-entendido” Eu não posso estar errado, porque de fato, Ruby possibilita acesso a estado protegido, assim como Smalltalk, aliás. Portanto, por essa definição, Ruby falha nos 3.
Meu ponto continua sendo: é irrelevante. Primeiro porque essa é uma opinião pessoal do Alan (enfatizando “to me”). Segundo, Smalltalk – por detalhes de implementação – também não vai 100% sobre tudo. Não seria inteligente, os compiladores podem trabalhar melhor se não tiverem limitações não-técnicas (conceituais).
Resumindo:
Alan Kay é um bom estudioso, na OOPSLA 98 ele defendeu os seguintes pontos (opinião dele, não é nenhuma lei): _“lembrar todos que Smalltalk NÃO é somente sobre sua sintaxe ou sua biblioteca de classes, não é nem mesmo sobre classes. Me desculpem que muito tempo atrás eu cunhei o termo ‘objetos’ para este tópico porque isso faz as pessoas focar na idéia menos importante.”)
“A grande idéia é ‘messaging’ (...) a chave para fazer grandes sistemas que crescem tem mais a ver com o design de como os módulos se comunicam do que suas propriedades internas e comportamentos deveriam ser. Pense na internet – para viver ela (a) precisa permitir muitos tipos diferentes de idéias e percepções que estão acima de apenas um simples padrão e (b) permitir graus variados de inter-operabilidade seguras entre essas idéias”
“Se focar apenas nas mensagens – e entender que um bom meta-sistema pode se ligar tardiamente (late bind) as várias arquiteturas de 2.o nível usado em objetos – então muito da linguagem, UI, e discussões baseadas em OS neste thread são realmente meio incertas. Foi por isso que eu reclamei na última OOPSLA que – enquanto no PARC nós mudávamos Smalltalk constantemente, tratando-a sempre como um trabalho em progresso – quando ele chegou ao mundo maior, foi praticamente tomado como ‘apenas algo a ser aprendido’, como se fosse Pascal ou Algol. Smalltalk-80 nunca realmente mudou para a próxima versão melhor de OOP. Dado o atual (1998) estágio baixo de programação em geral, acho que é um erro.”
Isso foi antes de Web Services, SOA e outros conceitos de late-binding e message passing de mais alto nível de abstração começarem a fazer sucesso. Foi justamente o conceito de troca de mensagens e late-binding que tornou os detalhes de implementação de cada linguagem irrelevantes. E Alan estava certo: não importa que linguagem está por baixo: eu posso fazer um sistema em C# que consome Web Services (seja em SOAP, seja em REST) escritas em ABAP – que tem pouquíssimas características OOP. Os 3 pontos de Alan anteriores estão coerentes. “Para ele”, uma linguagem OOP, tem “apenas” mensagens e late-binding extremo acima de tudo. É um desejo, não uma definição. Java não tem late-binding como característica principal, nem por isso ela não é possível. Pode não ser tão “clara” como em Ruby ou Smalltalk, mas funciona. Ok, ela é “quase” OOP. É suficiente por agora.
Claro, no nível da linguagem vem algumas ressalvas: eu consigo fazer um serviço Web em Ruby ou Python muito mais rápido do que em Java, C# ou ABAP. Porém, eu consigo desenvolver aplicações que se integram a outros pacotes SAP muito mais rápido em ABAP do que em Java ou Ruby. Por outro lado eu não vou conseguir fazer um aplicativo para celular que se integra com SAP em ABAP, vou fazê-lo em J2ME. Em não se estando limitado a ‘detalhes de implementação’ o trabalho é concluído.
Aliás, até mesmo “late binding” tem implementações e comportamentos tão diferentes que estudos como este acham que deveria haver uma especificação mais clara do que estamos falando. Espero que esse pesquisador continue seu trabalho. O problema? Via UML conseguimos expressar uma relação entre objetos, mas na hora de implementar os resultados saem diferentes de linguagem para linguagem. É um dos problemas de UML e da falta de especificação de orientação-a-objetos: UML seria mais efetivo se cada elemento pudesse mapear a um objeto real, com uma definição precisa. Ela não existe. Existem esforços para isso, mas ainda não se chegou a nenhuma conclusão.
“Preciso citar a falácia no argumento?”. Sim, precisa :-) Eu explico porque: você afirmou e implicou que Smalltalk é melhor porque é OOP puro, enquanto outras como Ruby e Python não são. Como foi você quem afirmou isso, o burden of proof na verdade é seu, mas sou eu quem estou explicando.
Por que eu estou reclamando?
Por que 1 e 2 precisam implicar 3? Tivesse você apresentado Smalltalk e Seaside à comunidade Ruby on Rails, SEM puxar o tapete de Ruby on Rails, eu corroborava. Eu já havia mencionado Seaside várias vezes antes – e notem: em todos os comentários aqui, e nos artigos, sou o primeiro a dizer que sim, Smalltalk e Seaside são excelentes – embora o Seaside esteja incompleto se comparar com Rails, mas é promissor, assim como Rails, quando era versão 0.4 também era! O fato de estarmos discutindo aqui não pode significar coisa boa.
Portanto meu problema não é com a tecnologia. Minha insistência no padrão? Como você espera fazer uma afirmação sem ter uma base? A afirmação “Smalltalk é melhor porque é OOP puro” só faz sentido se existir uma especificação, com um corpo de conhecimento baseado em evidências empíricas (não achismos do tipo “porque você acha Groovy existe” ou “porque a necessidade de AOP?” – vou chegar nesses pontos). Sem isso, a afirmação é vazia e nula – que é minha conclusão.
Agora, os Rubistas não são isentos. Eu mesmo já ataquei Java várias vezes. A famosa imagem da pilha de livros frente aos 2 de Ruby/Rails é um clássico. Ninguém negou a imagem porque é verdade: para se entrar no mercado de programação Java, é necessário uma bagagem muito maior. Não necessariamente daqueles livros, mas grande mesmo assim. Eu assumo aqui que isso é abertamente uma ferramenta de marketing. Puro hype! Isso porque apenas aquela imagem dificilmente é motivo para se mudar.
Java era comandado exclusivamente por uma empresa – a Sun – com um comitê – a JCP. O hype em torno do “poder” não só de Ruby, mas das linguagens dinâmicas em geral, fez a Microsoft investir no desenvolvimento da DLR (Dynamic Language Runtime), no incentivo da criação do Groovy e do JRuby dentro da Sun e finalmente na abertura do Java como GPL. Foi uma discussão política. Não apenas técnica. E era pressão sobre uma empresa gigante. Nós todos ganhamos com isso. J2EE é uma especificação, comandada pelo JCP. É uma faca de dois gumes: por um lado ela possibilita um mercado crescente de servidores de aplicação (tornou esses servidores uma commodity, assim como o SQL tornou os bancos de dados uma commodity). Por outro lado, era uma especificação fechada – o pessoal do JBoss passou por poucas e boas para certificar seu servidor. Todo código feito em Java corria o risco de ser fechada, caso a Sun resolvesse cobrar seus direitos sobre o Java byte-code. A mudança para o GPL é uma briga que durou 10 anos e teve uma boa conclusão.
Uma das discussões mais acirradas em torno de Groovy, Java e Ruby não foi seu mérito de ser OOP, isso poucos discutem. Foi sim a implementação de Closures e as especificações rivais que iriam disputar na JCP. A pergunta óbvia é porque Groovy, uma linguagem que foi criada do zero agora, não foi projetada para ser tão “puramente” OOP quanto Smalltalk? Por que implementar uma linguagem multi-paradigma? “Talvez”, porque o mundo da tecnologia caminha para multi-paradigma: o problema é encontrar qual o balanço certo de características que determina uma boa linguagem no todo: mais partes funcionais, diriam o pessoal do Common Lisp; mais partes objeto, diriam o pessoal de Smalltalk; tipos mais fortes, diriam o pessoal do Java; mais integração com legado, diriam o pessoal do .NET. E por aí vai.
Em 30 anos, por que é que tantos projetos falham? Eu não me atreveria a dar uma resposta categórica a isso. Institutos e empresas (IBM, principalmente) vem estudando o assunto a sério desde antes de Fred Brooks. Todos sabemos: “não existe bala de prata”. Não é o OOP. Não são os funcionais. Não são os compilados nem os interpretados, sozinhos, que serão a “bala de prata”. Os estudos vão para várias frentes: será a linguagem por ser mais procedural ou mais objetos? ABAP, Java, não, não sozinhas. Serão as metodologias? Waterfall, Agile, Unified Process, também sozinhos não. Serão os processos? CMMI, ISO 9000 sozinhos também não. Serão as pessoas? Talvez, existem muitos estudos psicológicos e comportamentais, mas também não é a única respostas. Como todos os problemas reais, as respostas reais também não são tão agradáveis quanto uma ‘afirmação dogmática’: são multi-facetadas e o truque é saber qual o balanço, qual a influência de cada fator. Para isso, só testando.
Eu abordei MVC porque você afirmou que MVC é ruim. Não sei sobre quais bases veio essa afirmação. E vamos cair no mesmo problema: sobre qual definição de MVC estamos falando? A clássica ou a da Sun? E mesmo assim, quais das implementações? E por que “somente” componentização é melhor? (Veja que a ressalva é justamente no “somente” – dogmas …) Tapestry não é componentizado o suficiente? WebObjects não é componentizado o suficiente? JFC não é componentizado o suficiente? Cada um tem pontos fortes e pontos fracos. Quando um deles diz que é o “melhor”, é marketing. Já não passamos por isso antes? Spring ou Struts? Framework X ou Framework Y.
Estou dizendo que a discussão DEVE existir, mas não em bases dogmáticas. Onde estão os argumentos técnicos, benchmarks, estudos de caso, apontando exatamente quais são os pontos fortes e fracos? Ou como fez o pessoal do PHP: por que não tem Rails em PHP? Ótimo: CakePHP. Por que não tem Rails em .NET? Ótimo: Castle. E por que não ter Seaside em Ruby? Avi sugeriu isso. Acho uma ótima idéia.
E continuamos… :-)
Primeiro, vamos tirar uma coisa do caminho. A afirmação de Alan Kay e
pessoal e eu não neguei isso em nenhum momento. Você está colocando como se
eu tivesse isso e pelo meu comentário é óbvio que não. A minha questão foi
que você disse que o Ruby passa nos três e eu disse que não.
Sobre a sua “confusão”, eu disse que Ruby falha em um critério básico e
realmente falha no aspecto de messaging, o que implica que extreme—com
ênfase aqui—late binding não é um absolutamente necessário e o uso de
tabelas virtuais normais é uma reflexão disso. Quando eu disse que você
estava errado, eu não disse que você estava errado ao dizer que Ruby não
tinha, mas ao dizer que isso era o problema a que eu estava me referindo.
Ruby usa, até onde eu sei, uma aproximação mista que se encaixa bem com sua
semântica e isso não está em questão.
Agora, voltando ao ponto. Eu não discuto a irrelevância. Como eu já disse
duas vezes, realmente é irrelevante dependendo da sua tarefa. Se você só
pode usar ASP, dizer que Smalltalk é melhor do que ASP-
o que é verdade-nãoajuda em absoluto. Mas existe termos em que uma linguagem, sim, é melhor que
a outra e nisso eu continuo a discordar. O que é basicamente o mesmo exemplo
que você deu. E isso tudo não ter absolutamente nada a ver com a questão que
eu levantei em contraposição ao seu argumento.
O seu ponto inicial era que ser puramente OOP é uma falácia. Eu discordo e
expliquei porque, sem usar a argumentação de Kay para isso. Usei um conceito
muito mais simplificado que você modificou, comentendo as falácias
mencionadas acima.
Dizer que Ruby é parcial e isso é tão bom não refuta a questão de que é
híbrida versus Smalltalk que é pura. O meu ponto, o tempo todo, está sobre
isso e não sobre ser melhor ou pior. O messaging do Ruby é muito limitado (e
o plugin Ambition do Rails é uma prova clara disso) e a aproximação pura do
Smalltalk se prova muito melhor nesse sentido (como também evidenciado pelo
Glorp). Você pode voltar ao ponto de Turing-complete e mais uma vez eu não
nego essa caracerística. Mas é muito fácil comparar as implementações e
mostrar que a característica de messaging pura do Smalltalk é superior para
a tarefa proposta em termos de implementação.
Eu sabia que o tópico de compiladores iria surgir e é claro que há
otimização. Mas uma coisa é você poder fazer e outra coisa ter que fazer. No
caso do Squeak, por exemplo, modificar o compilador é tão trivial quanto
qualquer outra tarefa (a implementação do Seaside no Dolphin também
demonstra isso também de maneira admirável). Dizer que uma hora chega no
compilador é a mesma coisa que dizer que uma hora chega em micro-code.
Passando pelas suas reclamações. Na palestra, sim, eu disse que o Smalltalk
era OOP puro e mantive isso aqui na discussão, mas não disse que por causa
disso ela era melhor que todas outras. No final eu disse que achava
Smalltalk a linguagem mais bonita (mais perfeita) que as outras, mas isso
não quer dizer que eu esteja dizendo que todo mundo só deveria usá-la. Essa
é uma opinião pessoal que não tem a ver com pureza ou não. É sintaxe, não
semântica.
No momento em que eu comparei a pureza OOP, eu disse que o Rails e o Django
não usavam OOP puramente. Note que eu passei para o framework porque
realmente o uso que o Rails e Django fazem de MVC tente a esconder a
orientação a objetos e isso é algo péssimo. O Giles Bowkett manifestou
recentemente o seu medo de que os piores empregos em 10 anos fosse manter
aplicações Rails espaguete por causa desse problema. Esse é um problema que
não acontece no Seaside porque não há metáfora, mas o uso puro e absoluto da
linguagem. E isso volta ao ponto inicial de uso necessário.
Quanto à apresentar o Seaside duas considerações. Primeiro, eu não
apresentei à comunidade Ruby. A palestra era aberta e não há como dizer que
eu represento a comunidade ou que estou na frente porque eu já disse dezenas
de vezes que uso Rails relativamente pouco. Nos anos de Rails que eu tenho,
já escrevi vários artigos defendendo o Rails e continuo a defendê-lo. Aliás,
eu dou um curso de Rails, se você não notou. Dizer que eu puxei o tapete é
uma afirmação pueril. Eu critiquei o Rails, sim, e não vejo porque não posso
criticar. E se discussão não é uma coisa boa, não sei porque você fala tanto
em lógica se uma das premissas inerentes à mesma é a necessidade de
discussão.
O Rails realmente sofreu um marketing extensivo e isso é bom porque chamou a
atenção para linguagens dinâmicas. Isso é valioso e unindo hype à capacidade
técnica, a comunidade Ruby/Rails virou o mundo. Não nego e concordo.
Agora, se você puxa a discussão para isso e começa a atacar quem está
discutindo, realmente não devíamos ter a dicussão. As minhas perguntas
“porque o Groovy existe” e “porque a necessidade de AOP” são considerações
válidas e demonstram o ponto que eu estava fazendo. Se você precisa interferir por fora na linguagem, o arcabouço da mesma não é completo. Você pergunta porque Groovy não é puramente OOP. A questão não é porque ela não é pura, mas porque precisa existir. E se você viu o meu comentário sobre o livro Dreaming in Code e minha palestra sobre linguagens de programação, sabe que eu não acredito em silver bullets. Volto ao mesmo ponto de ferramentas certas para o trabalho, mas também faço o ponto de que a falha está implícita no fato de que a JVM está se diversificando e que o dinamismo é uma resposta a isso.
Eu não sei onde eu disse que MVC é ruim e gostaria que você me dissesse para que eu possa inferir o contexto. Na palestra, alguém perguntou sobre MVC e eu disse que o Seaside não enfatiza isso tanto o que é irônico porque Smalltalk sempre esteve associado a isso. Muitos diriam que Seaside é MVC e estaria corretos, mas a ênfase não é essa. MVC é um desenho, é algo que pode ou não ser usado.
Eu sinto muito, mas o seu último comentário foi uma mistura de asserções pessoais e pouca discussão real. Eu gostaria de discutir em uma base mais tranqüila, mas acusações do tipo de puxar tapete e dogmatismo realmente não me animam muito.
Em tempo, existe Seaside para Ruby. Dois por sinal: Wee e Borges. Basta baixar e continuar a desenvolver.
Formatação maledeta. :-)
Caramba… ô discussão longa :) Vcs são máquinas de escrever!!!
Gostei dos pontos de vista, embora tenha caído um pouco para o “sexo dos anjos” (IMHO).
Méritos a parte, voltamos ao ponto de: “use o que goste” :D ou não?
Qto a ser 100% OOP ou não… cai naquela música dos muppets “Manah Manah” (bem no finzinho)... “The question is ‘what’s a manah manah?’”... “No, the question is ‘who cares?’” :)
Eu e minha boca grande ;)
O assunto é interessante. Defendo o lado das linguagens multi-paradigma, por simplesmente acreditar que cada paradigma possui boas coisas a oferecer. A alquimia do negócio é saber a mistura correta dos ingredientes.
A orientação a objetos é um paradigma fantástico, mas o funcional também é. Se a linguagem me permite passar com facilidade o que tenho em mente para o código, isso é ótimo.
Não sou muito versado no tema, mas um estudo breve me fez crer que boa parte da funcionalidade do Design by Contract pode ser obtida com testes automatizados (ex: testes unitários).
Estou certo?
Não resisti entrar nesta discussão dormente..
“Ruby é uma linguagem O.O., com aspectos funcionais, tipagem forte e dinâmica, e interpretada. Smalltalk é O.O., sem aspectos funcionais relevantes”
Em que aspectos funcionais as duas linguagens divergem???
“Porém: qual a vantagem prática de ser “puramente OO”?”
Você mesmo citou uma vantagem: consistência.
Tendo observado a vida até aqui, acho razoável pensar que as leis naturais são a própria definição da consistência, e quando não são, o problema está nos nossos olhos. Modelos limitados servem à propósitos limitados e específicos e, portanto, não oferecem uma base boa o suficiente para uma expressão genérica ou permitem que o conhecimento obtido seja empregado em outras áreas do saber e da atividade humana de forma coerente. Além de, potencialmente, prejudicar a comunicação e a compreensão geral dos problemas, isso impacta em outra vantagem: escalabilidade. Onde um conceito consistente e uniforme escala (para baixo, para cima [ou para os lados]), um conceito impregnado de excessões tem um teto definido. Isso tem profundas implicações.
A pureza implica a busca por um modelo abstrato genérico, ou o minimo denominador comum, que possibilite à nós pensarmos sobre um amplo conjunto de coisas nos mesmos termos, usando apenas abstrações sobre as regras básicas. Modelos menos puros exigem que eles mesmos (os modelos) sejam constantemente adequados e atualizados para satisfazer outras modalidades de expressão. Cada atualização do modelo implica em novos conceitos estrangeiros que forçam suas definições em termos estrangeiros. Isso tudo tende ao aumento da complexidade. Sendo assim, a terceira vantagem que deduzo é: simplicidade.
A propósito, dizer que “o máximo que podemos efetivamente afirmar sobre uma linguagem é se ela é Turing Complete ou não” é, a meu ver, como dizer que não há nada que possamos afirmar sobre quadros, a não ser que eles são coloridos ou preto/branco.
“Assim como são coisas não-OO como classes abertas (mixins) e até mesmo tipos primitivos não-objetos em muitas circunstâncias.”
Mixins, não-OO??