É polêmico, claro, mas nada oportunista ou tomando partido de algo.
Em 04/06/2009, Marcos Dell Antonio <marcosde...@gmail.com>
escreveu:
> O interessante nesse caso é que o autor do artigo é o Dalton Camargo, que
> foi o responsável pelo desenvolvimento e implantação do novo fórum de jogos
> do UOL.
>
> Eu conheço ele. Só não sei dizer porque ele escreveu um artigo como este...
>
> 2009/6/4 Rafael Rosa <rafael...@gmail.com>
>
> > Poucos sites são tão inúteis quanto o JavaFree. Uma vez publicaram um link
> > para um post do Carlos Brando, que trabalha comigo no Ruby Inside Brasil, e
> > colocaram a chamada deturpando a mensagem dele. O que vêm de lá eu
> > desconsidero.
> >
Em 04/06/2009, Dilter Porto <dilter...@gmail.com> escreveu:
> Este artigo não parece ter sido escrito recentemente. Ou o autor só
> consultou informações antigas a respeito do .NET. Fazendo sitações ao J#
> (descontinuado), se referindo ao VS como Visual Studio .NET (geralmente
> usado para se referir à primeira versão da IDE.
> O artigo é morno, na minha opinião.
>
Quando disse que não vi nada demais é por que penso assim tb. Ele
escreveu um artigo sóbrio, sem "a microsoft é do mal", comparando
no ponto de vista dele. Não acrescentou nada de útil, não disse
nenhuma mentira nem inventou baboseiras. É um artigo frio, sem nada
a acrescentar, como vc disse. Ou como eu disse, nada demais.
Em 04/06/2009, Marcos Dell Antonio <marcosde...@gmail.com>
escreveu:
"No item escalabilidade, as implementações das duas plataformas provêem mecanismos de balanceamento de carga, permitindo habilitar um cluster de máquinas para servir às cargas dos usuários que forem aumentando ao longo do tempo. A grande diferença entre o J2EE e o .NET é que desde que o .NET suporta apenas Win32, um número maior de máquinas se faz necessário, comparando ao J2EE, devido às limitações dos processadores. "
"Em um fator de extrema importância, como velocidade de desenvolvimento, o .NET leva grande vantagem. A sua IDE proprietária, o Visual Studio, é baseado em RAD (Rapid Application Development), aumentando a agilidade na construção de aplicações. O Visual Studio .NET inclui várias ferramentas interessantes em termos de produtividade, como por exemplo o Web Forms. Estima-se que um projeto criado do zero, leve-se de 10% a 20% menos tempo para entrar em produção quando desenvolvido em .NET. "
"O Microsoft .NET oferece independência de linguagem, permitindo os componentes serem escritos em VB.NET, C# e J#, por exemplo. (...) Com um conjunto de linguagens rodando sobre a plataforma .NET, os desenvolvedores diminuem a habilidade de compartilhar as melhores práticas, diminuindo a assertividade do compartilhamento de informações. Assim, especula-se que um conjunto de linguagens rodando em CLR pode levar a uma combinação de código espaguete que fica difícil de manter. Com a liberdade para se utilizar diversas linguagens, a aplicação torna-se mais complexa, necessitando de experts em diferentes linguagens, o que também faz aumentar o TCO e a entropia do sistema. "
"As duas tecnologias apresentam uma curva de aprendizado parecida, com a diferença de que o Java possui mais material para aprendizado na internet do que o .NET, que é proprietário e a principal fonte de conteúdo é o MSDN."
Analisando o último quesito, portabilidade, praticamente não há o que comparar. Como já dito na coluna anterior, o Java segue o princípio write once, run anywhere, permitindo executar as aplicações na virtual machine em praticamente qualquer ambiente. O .NET roda apenas no Windows, no seu hardware suportado, e no ambiente .NET. Há algumas implementações adicionais do .NET que rodam em outras plataformas, porém que não permitem o uso de todo o potencial do framework.
2009/6/5 Giovanni Bassi <gig...@giggio.net>:
> Pelo que entendi ele quer dizer que o .Net não suporta 64 bits. Só que
> suporta sim, desde a versão 1.0. Desinformação. Ou seja, desconsiderado.
Acho que ele estava falando em relação a sistemas operacionais, mas
realmente ficou confuso. De qualquer maneira quem coloca clusters como
escalabilidade razoável em 2009 dificilmente teve que lidar com
problemas sérios de escalabilidade.
> Se considerar
> que no Java usam-se 300 frameworks para fazer uma coisa, e que cada vez que
> você contrata um desenvolvedor precisa ensinar ele a usar o framework que
> você utiliza, já perde mais uns 10%. Colocando outras possibilidades, como
> delegates, enums (que o Java só recebeu recentemente), LINQ, etc, vai mais
> uns 10%. Ou seja, dá uma produtividade de até 40% a mais... Ainda bem que
> desenvolvedor é barato, e que o caro é máquina, não é? Ops, acho que é o
> contrário...
Assim como eu vejo diversos pontos errados no texto original tenho que
pedir para que mantenhamos o FUD fora desta lista. Em java existem 300
frameworks para fazer qualquer coisa da mesma forma que existem tantas
possibilidades de resolver qualquer problema. Ter poucas opções não só
não é bom bem como não garante produtividade nenhuma -muitos projetos
.Net que eu tive que lidar com acabaram criando seu próprio framework
caseiro.
> O primeiro absurdo é o cara jogar no lixo o conceito de melhor ferramenta
> para o trabalho. Linguagens funcionais onde o esforço é cálculo, matemático,
> etc. Linguagens dinâmicas onde é possível. Linguagens estáticas são ainda
> uma opção, e linguagens nativas para trabalhar no baixo nível.
Não sei exatamente de onde você tirou estas definições de "cenário
ideal" mas elas são bem problemáticas. Misturar tipagem (estática,
dinâmica, etc.) com paradigma principal (funcional, OO, etc.) não faz
o menor sentido. Você pode ter linguagens OO estáticas ou dinâmicas
(Java/C# e Ruby) assim como pode ter linguagens funcionais estáticas
ou dinâmicas (Haskell e Scheme).
> Algumas, como
> o C#, trazem conceitos de todas (nativa, funcional, dinâmica e estática).
Não sei exatamente onde C# tem algo de linguagens de tipagem dinâmica
(dado que inferência de tipos é bem comum em linguagens estáticas).
Também não entendo o que C# tem de funcional, a menos que você conte
lambdas que são comuns em dezenas de linguagens não funcionais.
> Esse grupo não está no MSDN. O codeplex não está no MSDN. Pode ser impressão
> minha, mas sempre que procurei ajuda em Java, tive muito mais dificuldade.
> Aos fluentes nos 2 mundos, poderiam dar seu feedback (Philip, André, etc)?
Estando de volta à .Net após um longo período (o último projeto foi em
2006) posso dizer que sim, é bem mais difícil achar informação *de
qualidade* em .Net. A documentação de referência não é suficiente -bem
como a documentação oficial do Java nunca foi suficiente- e nas
últimas duas semanas o que tem me salvado são os livros e as listas
como esta. Os blogs e artigos de revista geralmente parecem estar mais
interessados em mostrar em qual botão clicar (com screenshot!) do que
nos porques e melhores técnicas.
> Até onde sei, servidores de baixa
> plataforma rodam tanto Linux quanto Windows, com a diferença que você não
> tem que ficar caçando drivers na rede para o Windows, o Windows Update cuida
> disso pra você.
Desculpe mas isso é mais FUD. A última vez que tive que procurar
driver para placa de rede em uma máquina com Linux foi há mais de
cinco anos.
> Sou fã das ferramentas, são linguagens 100% OO, posso usar a linguagem que
> quiser (adoro isso).
C# não é 100% OO (não que isso importe na prática).
> Por fim, IMHO, o JCP, que é a organização que decide o futuro do Java,
> impede muito o progresso do Java. Ok, é "democrático", mas e daí? Ok, o Java
> é open source. E daí? As empresas sérias esperam um release oficial, não
> saem por aí, com poucas exceções, reconstruindo o Java, enfiando delegates
> no Java enquanto o JCP não decide se vai entrar ou não.
Isso não condiz com minha experiência. Se você contar apenas a JVM eu
já trabalhei com mais de 6 fornecedores diferentes -o que era muito
comum antes do HotSpot da Sun se tornar excelente. Em três empresas
nós utilizamos em produção uma máquina virtual com patches ou escritos
por nós mesmos ou que nos foram enviados pelo suporte da Sun como
código-fonte antes de serem incluídos na distribuição oficial.
> Fora que esse lance de open source é uma brincadeira. No board final de
> decisões do JCP estão IBM, Oracle, Sun, BEA (ou seja, Oracle, Oracle e
> Oracle), etc. Na prática, o que a Microsoft faz sozinha, de forma
> monopolística (sic), é feito por um oligopólio, que tem a Oracle como membro
> triplo-votante. Isso pode até ser alerdeado com o democracia, mas não é.
> Essas empresas lutam no JCP para enfiar na linguagem coisas que façam
> sentido para suas estratégias comerciais, e fingem-se de bem intencionadas
> através de um processo OS. Hipocrisia até a última gota. Pior que tem quem
> compre essa baboseira.
Desculpe mas isto é mais FUD. O JCP não é o melhor processo do mundo
mas a simples existência do EJB 3 -criado pela comunidade, apoiado por
um fornecedor open-source de tamanho muito pequeno e que se tornou
padrão contrariando coisas grotescas e altamente lucrativas como
UIX/BC4J da Oracle- mostra que as coisas não são assim.
> E com o Eclipse é a mesma coisa.
Ahm?
Fico bem decepcionado em ler este tipo de email nesta lista. É a
primeira vez que eu participo de uma comunidade brasileira de .Net
exatamente porque pela primeira vez vi algo em português que não tinha
este tipo de pensamento de que "opções são ruins", "JCP não presta" e
que "Java é uma droga". Se alguém escreve um artigo falando
extremamente mal informado sobre .Net será que temos que reagir da
mesma maneira sobre Java? Será que não é melhor tentarmos entender que
em 2009 temos conhecimento e maturidade como indústria o suficiente
para que utilizemos as arquiteturas que façam mais sentido para um
dado cenário?
Deixo meu convite para que pensemos melhor e voltemos a discutir sobre
o que conhecemos e sobre o que queremos conhecer.
[]s
--
Phillip Calçado
http://fragmental.tw
http://www.fragmental.com.br
Exato. Eu não falei que Java é 100% Orientada a Objetos, qualquer um
que escreva um programa usando reflection vai ver que mesmo com
autoboxing você sempre tem que lidar int e Integer como coisas
diferentes. Aliás, Gilad Bracha escreveu recentemente sobre como isso
é o "pecado original" desta linguagem:
http://gbracha.blogspot.com/2009/05/original-sin.html
Ruby é dita ser 100% OO. Para mim o fato de que existe diferença entre
blocos e procs faz com que isso não seja verdade.
"Será que não é melhor tentarmos entender que em 2009 temos conhecimento e maturidade como indústria o suficiente para que utilizemos as arquiteturas que façam mais sentido para um dado cenário?"
2009/6/8 Giovanni Bassi <gig...@giggio.net>:
> Entendo que uma linguagem dinâmica não possui somente a tipagem dinâmica. O
> modelo de dispatch, por exemplo, tem que ser dinâmico também. Tipagem é só
> mais uma característica...
Ok, é sua definição pessoal mas não entendo no que dynamic dispatch
seria relevante dado que Java e C# -e basicamente qualquer linguagem
que tenha polimorfismo- o possuem.
> Misturei os conceitos porque são características que dominam a maneira como
> as linguagens são utilizadas. Por exemplo, Ruby é uma linguagem orientada a
> objetos dinâmica, mas quando falamos de Ruby não falamos de uma linguagem
> OO, mas de uma linguagem dinâmica. O mesmo para F#: é funcional, e é OO
> (multi-paradigma), mas é vista principalmente como uma linguagem funcional.
Novamente é a sua opinião, ok.
Para mim continua não fazendo sentido mas creio que temos opiniões diferentes.
> Quanto ao C# ter características dinâmicas, veja aqui:
> http://unplugged.giggio.net/post/C-40-Uma-linguagem-dinamica.aspx
No seu último email você não afirmou que estava falando da futura
versão de C#. Meu email trata de tecnologias e técnicas que estão
disponíveis, do contrário poderíamos, por exemplo, estar discutindo
sobre as propostas de closures para Java.
> Veja que nesse caso, a tipagem é estática, mas o dispatch é dinâmico.
Acho que estamos com conceitos bem diferentes sobre dispatch dinâmico
aqui. Dispach dinâmico é apenas o ato de não fazer a ligação entre
identificador do método (ou equivalente) à sua implementação durante a
compilação, fazê-lo apenas em runtime. Como disse anteriormente tanto
Java quanto C# utilizam isso para implementar polimorfismo. O que seu
artigo fala é -novamente- sobre tipagem dinâmica.
> Da mesma forma que o objeto é o conceito mais importante em OO, a função é
> em uma linguagem funcional. E as lambdas trazem a função à tona no C# como
> conceito de primeiro nível. Isso já podia ser feito antes como delegates
> anonimos, mas as lambdas facilitaram e deixaram o código mais explícito, o
> que é um grande passo. Quanto à várias linguagens implementarem lambdas,
> isso só reforça o conceito.
Não é bem por aí. Creio que você está fazendo uma confusão entre
linguagens funcionais e higher-order functions. O que C# e Ruby
possuem é a última característica, o que não caracteriza uma inguagem
como funcional.
> Não estou sozinho nesta opinião, o mercado
> entende que, sim, as lambdas são a característica funcional do C#.
Eu não confio no "mercado" quando o assunto são linguagens de
programação. O mercado afirma o que for mais interessante, ao
contrário da ciência da computação que tende a afirmar algo apenas
após pesquisas e resultados.
> Legal seu feedback com relação à busca de informação em .Net. Será que é
> porque originamos de mundo diferentes, e quando procuro algo em Java também
> tenho dificuldade, da mesma forma que você no mundo de .Net? Faz sentido?
> Alguns sites, como o stackoverflow.com são excelentes fóruns de discussão, e
> não só de .Net. O que falta exatamente? De repente tem uma oportunidade aí,
> algo não atendido. O que o mundo de Java tem que o mundo de .Net não tem
> nesse sentido?
Acho que falta profundidade. É o mesmo problema que tenho, por
exemplo, em Rails e Cocoa (desenvolvimento para IPhone): existem
zilhões de tutoriais mas ninguém está interessado em explicar o porque
de alguma coisa. Em Rails eu geralmente leio o código fonte.
Felizmente ao contrário de minha experiência em 2005-2006 com .Net
hoje em dia existe muito código aberto (ainda que não livre) pela
Microsoft e é possível adotar a mesma prática. No caso do IPhone é
sentar e chorar.
> Eu não vivo em um mundo de Java, mas nunca vi um cliente alterar a JVM, nem
> em clientes grandes, nem pequenos. Mas, como eu disse, não vivo nesse
> mundo... de qualquer forma, entendo ser algo arriscado. E se a linguagem
> evoluir para o lado oposto? Você perde as customizações que fez no código?
> Nesses cenários que você citou, a empresa evoluia o Java independentemente,
> acrescentando ou mundando comportamento e sintaxe?
Nestes casos não houve mudança na sintaxe e sim na JVM. Na maioria das
vezes eram bugs a serem corrigidos. Eu trabalhei em diversas empresas
que integravam C++ com Java e a quantidade de bugs que só aconteciam
em uma determinada versão de SO com uma determinada versão de Java e
uma determinada versão de GCC ou VC++ era enorme. O poblema é que
exeto por noso projeto ninguém mais no mundo ligava para este
problema. A solução muitas vezes foi escrever o patch, outras foi
pagar suporte da Sun e receber um patch.
As modificações geralmente são enviadas de volta ao mantenedor
(antigamente seria a Sun, hoje existe o projeto OpenJDK) e quase
sempre eram incluídas. Quando não o foram a empresa pelo menos ganhou
tempo para remover a causa do problema -geralmente fazendo upgrade de
SO ou compilador- antes de migrar para a próxima versão de Java.
> Philip, não entendo como é possível que você ache que o JCP está evoluindo o
> Java com uma velocidade boa. Os caras demoram anos para concluir as
> coisas... Enfim, vai ver eu estou mal acostumado...
Eu não disse isso. O que eu disse é que sua afirmação sobre o JCP ser
uma "baboseira" não era verdade e dei um exemplo. O JCP é extremamente
lento e ineficiente mas nos áureos tempos de Java (i.e. 2003-2006)
isso nunca foi problema porque o JCP nunca inovou de verdade (e quando
o fez sempre foi uma tragédia). Como no caso de Groovy, Hibernate,
Spring e tantos outros o que o JCP faz de melhor é apenas criar um
padrão para unir diversas teconogias já estabelecidas.
Isso é um problema para a *linguagem* Java porque dificilmente se
conseguiria evoluir uma linguagem tão amarrada quanto Java sem ter que
envolver todo um comitê -como contra-exemplo recomendo uma leitura
sobre como CLOS, o sistema OO de Common Lisp, foi desenvolvido sem
modificar a linguagem. IMHO isso foi uma das grandes causas do
esvaziamento de Java (linguagem) mas acredito que hoje a comunidade
esteja relativamente satisfeita ao se partir em dezenas de linguagens
que rodam na JVM.
> O que eu disse do Eclipse, é que grandes empresas colocam muito dinheiro
> para evoluir a ferramenta de acordo com suas aspirações comerciais, e vendem
> isso como trabalho comunitário. Não gosto dessa atitude. Se é pelo lucro,
> que assuma isso.
Este é um ponto interessante, entretanto eu não concordo com seu
argumento. A maioria dos projetos de software open-source são fundados
por empresas que lucram em cima deles.
O Eclipse é uma ótima IDE -apesar de ter entregue muito pouco em suas
duas últimas versões- mas o projeto tem diversos problemas causados
pelo fato de ser um consórcio. Eu conheço pessoas dentro da Eclipse
Foundation e o grande problema que eles têm é certamente o que
qualquer organização tem após criar uma plataforma de sucesso: não há
mais como se movimentar rapidamente. Uma mudança brusca -consertar a
terrível API do SWT, por exemplo- envolve quebrar milhões de produtos
de milhões de fornecedores diferentes.
> Quanto à opção, veja bem: o fato de, de certa forma, muitas empresas
> esperarem a Microsoft lançar para usar alguma ferramenta ou conceito, tem
> dois lados. O primeiro é que simplifica o mercado, e é muito fácil
> reaproveitar o profissional, que é o recurso mais caro em TI hoje em dia. O
> segundo, que é ruim e decorre do primeiro, é que muitos conceitos bons não
> são usados porque não há ferramenta Microsoft oficial que suporte o
> conceito. Um exemplo: mocks. Não há framework de mocks da Microsoft, e muita
> empresa não usa porque não há um "oficial". Isso é ruim. Da mesma forma,
> mesmo tendo ORMs muito bons, só agora, que o Entity Framework foi feito, é
> que a maioria do mundo de .Net está olhando esse assunto com seriedade.
Eu adicionaria à sua lista o fato de que muitas vezes a ferramenta
ofical é uma bela porcaria. Para tentar evitar polêmica desnecessária
eu vou dar um exempo em Java: EJB 2.1. EJBs eram *a* forma de forma de
fazer computação distribuída em Java, muitas empresas utilizam até
hoje porque é suportado por IBM, Oracle e etc.
Entretanto, como disse no meu email anterior, era uma bela porcaria. O
que a comunidade fez foi tentar resolver este problema de modos
diferentes, daí surgiram os 300 frameworks para mesma coisa. O detalhe
importante é que dos 300 frameworks geralmente apenas um ou dois são
amplamente utilizados mas os outros continuam como opções.
> Por fim, respondendo à sua pergunta:
>>
>> "Será que não é melhor tentarmos entender que em 2009 temos conhecimento e
>> maturidade como indústria o suficiente para que utilizemos as arquiteturas
>> que façam mais sentido para um dado cenário?"
>
> Entendo que por arquitetura você está falando desta discussão toda em volta
> de linguagens e sistema operacionais.
Não. Estou falando em arquiteturas heterogêneas. Como um exemplo posso
dar meu projeto atual que é um site com um volume monstruosos de
acessos. O projeto é em .Net mas eu estou usando diversos componentes
que são usados em arquiteturas UNIX (memcached, ngnix, Apache,
Squid...). Eu não estou preso à .Net ou UNIX, estou preso ao que
representa o melhor custo/benefício.
> Eu entendo que o valor do .Net é maior em muitos desses cenários. Entendo
> que um profissional de Java discorde de mim, e isso faz parte. É uma
> discordância profissional, e cada um fique com o que entende como melhor.
Um ponto interessante aqui é que há muito tempo eu não me considero
"um profissional de Java". Eu sou um desenvolvedor de software que
conhece uma quantidade razoável de plataformas e tenta utilizar a
melhor para cada caso. Tenho minhas preferências mas isso não define
que profissional eu sou.
> Por fim, o que o C# não tem de 100% OO? Herança múltipla não é obrigatório
> no meu entendimento. OO não é algo fechado, 100% definido. Não há uma
> organização que defina o que é OO ou não.
O critério mais comum para algo ser 100% Orientado a Objetos é quando
tudo na linguagem é um objeto. Nem Java nem C# possuem esta
característica. Value types em C#, primitivos em Java -e autboxing é
apenas um workaround feito pelo compilador.
2009/6/9 Giovanni Bassi <gig...@giggio.net>:
> Eu acho que isso aqui está ficando muito grande. Vou tentar ser breve...
> Quanto à dispatch dinâmico: em C# (.Net em geral), a ligação é em tempo de
> compilação. Somente com o DLR é que o Dispatch passou a ser realmente
> dinâmico, ou seja, resolvidoem tempo de runtime. Mesmo com polimorfismo, a
> ligação da chamada do método é feita em tempo de compilação. Não há, por
> exemplo, avaliação de qual overload vai ser chamado em tempo de execução.
> Portanto, a ligação é estática. Isso só será possível agora com o DLR.
> Antes, com reflection, havia essa possibilidade, mas não era a mesma coisa.
Parece que estamos com definições *bem* diferentes de dynamic
dispatch. Como você disse static dispatch é quando a implementação
para os métodos são encontrados em compile time. Este é o default em
C# mas a coisa muda de figura quando você marca um método como
virtual. Um método virtual possui dynamic dispatch, por isso que você
não precisa recompilar uma dll de terceiros para estender uma classe,
por exemplo.
Uma referência:
Este livro é altamente recomendado, um dos poucos sobre linguagens de
programação que usa exemplos em linguagens mainstream como C#, Java e
Ruby.
> Quanto à linguagens funcionais: segundo sua definição, então o F# também não
> é uma linguagem funcional, e nem o OCAML, do qual ele é uma simplificação.
Eu não me lembro de ter dado nenhuma definição de linguagem funcional,
apenas de dizer que higher-order functions não fazem de uma linguagem
funcional.
> Eu não disse que C# era uma linguagem funcional, mas que tinha
> características funcionais.
Correto, eu acabei passando por cima do que você disse.
> Continuo achando que opções demais é ruim. Na prática essas opções demais
> não existem, como você mesmo disse, já que só um ou outro sobrevive. O que
> sobra é barulho.
Não. As opções existem, muitas vezes você precisa utilizar um
framework de nicho para solucionar um problema específico. Como
exemplo rápido, ano passado eu desenvolvi um sistema que era um
instance-based component, algo que era distribuído como um arquivo JAR
que outras pessoas utilizariam em seus projetos. O projetinho cresceu
e precisávamos de algo como um framework de injeção de dependências.
O framework mais mainstram em Java é o Spring mas este possui centenas
de recursos que não utilizaríamos e acrescentaria alguns megabytes ao
nosso projeto. Solução? PicoContainer. Um ótimo framework para injeção
de dependências que não tem nem metade do público do Spring. Opções
são boas.
> Quanto ao JCP: baboseira é essa história de ser comunitário, não o processo
> todo. É algo dirigido, é isso que eu disse. Comunitário é ilusão.
Foi exatamente isso que eu combati. É a terceira vez que eu trabalho
em uma empresa que faz parte do JCP e minha experiência não
corresponde com esta afirmação.
> Entendo que você não se coloque como "profissional de java", e respeito
> isso. No entanto, eu não acredito ser possível acompanhar a quantidade de
> tecnologias que estão surgindo, e ainda fazer isso em n plataformas em
> paralelo. Hoje eu estudo a fundo o .Net. Conheço C#, VB, J#, C++, IronRuby,
> F#... Algumas linguagens mais que as outras. Conheço ASP.Net WF, MVC,
> Windows Forms, WPF, entlib, NH, Silverlight, Mobile, XNA, ADO.Net, EF, WCF,
> WF, etc, etc, etc... a lista não para. Algumas mais do que outras também. Se
> eu tivesse ainda que focar em Java, meu conhecimento em .net seria
> infinitamente mais superficial, por um só motivo: não há tempo. No mundo de
> hoje, foco é fundamental. Acho um diferencial importante você conhecer
> memcache, só não acho que vou investir nisso, porque há coisas mais
> importantes no próprio .Net a avaliar.
Bom, eu discordo largamente. O que importa são conceitos, as
implementações são sempre muito parecidas. O Velocity da MS, por
exemplo, é uma outra implementação do mesmo conceito do memcached.
Acredito que ao se aprofundar mais nos conceitos (e daí parte minha
crítica anterior aos blogs de .Net) a implementação importa muito
pouco. Essa ao menos é minha experiência.
> Ficou faltando você dizer os recursos de documentação/suporte de Java que o
> .net não tem...
Não entendi este ponto, é com relação à minha crítica aos blogs?
> Ficou faltando você dizer os recursos de documentação/suporte de Java que o
> .net não tem...
Não entendi este ponto, é com relação à minha crítica aos blogs?
.method private hidebysig instance void ChamaC1() cil managed { .maxstack 1 .locals init ( [0] class ConsoleApplication2.Class1 c1) L_0000: nop L_0001: newobj instance void ConsoleApplication2.Class1::.ctor() L_0006: stloc.0 L_0007: ldloc.0 L_0008: callvirt instance void ConsoleApplication2.Class1::Virtual() L_000d: nop L_000e: ldloc.0 L_000f: callvirt instance void ConsoleApplication2.Class1::NaoVirtual() L_0014: nop L_0015: ret } .method private hidebysig instance void ChamaC2() cil managed { .maxstack 1 .locals init ( [0] class ConsoleApplication2.Class2 c2) L_0000: nop L_0001: newobj instance void ConsoleApplication2.Class2::.ctor() L_0006: stloc.0 L_0007: ldloc.0 L_0008: callvirt instance void ConsoleApplication2.Class1::Virtual() L_000d: nop L_000e: ldloc.0 L_000f: callvirt instance void ConsoleApplication2.Class1::NaoVirtual() L_0014: nop L_0015: ret } |
2009/6/9 Giovanni Bassi <gig...@giggio.net>:
>> Não entendi este ponto, é com relação à minha crítica aos blogs?
>
> Você havia dito que em Java é mais fácil achar informação. O que há em Java
> que não há em .Net? De repente conseguimos preencher um gap...
Como falei antes falta profundidade nos blogs e artigos técnicos.
> Quanto ao dispatch dinâmico, realmente estamos falando coisas diferentes.
> Porque, se for assim, todas as chamadas no C# são virtuais. O livro
> mencionado falha largamente em mencionar esse tipo de coisa. E mesmo nesse
> caso, não há dispatch dinâmico, a ligação é em tempo de compilação. Veja um
> exemplo:
Em uma pesquisa no Google achei alguns resultados interessantes sobre
o que dos métodos não-virtuais serem "virtualizados" pelo compilador:
http://stackoverflow.com/questions/845657/why-is-the-c-compiler-emitting-a-callvirt-instruction-for-a-gettype-method-cal
http://barrkel.blogspot.com/2006/05/call-vs-callvirt-for-c-non-virtual.html
http://www.eggheadcafe.com/software/aspnet/34026727/why-callvirt-on-sealed-ty.aspx
Ou seja: basicamente uma otimização do compilador. Uma coisa boa desta
discussão é que acabo de adicionar o livro mencionado no Stackoverflow
no meu shopping cart, parece bem interessante.
Mas antes de mais nada é importante não confundir a linguagem com sua
implementação. Uma linguagem pode ser implementada de diversas
maneiras, o bytecode gerado pelo compilador não faz parte da
linguagem, ele vai ser otimizado e perder semântica.
E o livro que eu recomendei fala sobre a linguagem de programação e
não sobre a implementação A ou B. Mas se não gostou do livro não há
problema, basta consultar outras obras sobre linguagens de programação
(até a wikipedia!) e pode-se perceber, como falei antes, que se C#
fosse apenas baseada em static dispatch não conseguiria estender uma
classe definida dentro de um binário e tê-la participando de uma
operação polimórfica sem ter que recompilar o binário, dado que quando
o binário foi compilado sua classe não existia.
Mas ainda que a implementação fosse levada em conta o exemplo que você
postou a mim só prova que -por um detalhe de implementação, não pela
linguagem- toda invocação de método em C# é feita por dynamic
dispatching e não apenas métodos virtuais!
Estaria muito interessado em ver alguma referência do que para você é
dynamic dispatching mas, sinceramente, eu paro este assunto por aqui.
Existe literatura mais que abundante sobre o assunto disponível
gratuitamente na Internet para pesquisa e não acho que eu consiga
explicar melhor que a bibliografia. Eu entendo que a nomenclatura
confusa dificulta o entendimento mas dynamic e static dispatch models
são conceitos bem antigos em ciência da computação.
Obrigado pelas referências. Eu conheço a MSDN e a utilizo
frequentemente, infelizmente ela não supre todas as dúvidas, bem como
nenhuma documentação de fornecedor nenhum o vai. O meu ponto não é que
a MSDN é incompleta -creio que não falei isso aqui- mas que a
documentação em .Net em geral não se foca no "porque" e sim no "como".
Eu entendo que isso não é visto como um problema pela maioria das
pessoas então não quero convencer ninguém sobre isso.
Sobre dynamic dispatch acho que você não entendeu bem. Não apenas não
é um pattern -é uma característica de uma dada linguagem de
programação- bem como você não precisa de reflection para verificá-lo
em C#, basta usar polimorfismo puro e simples.
[]s
2009/6/9 André Dias <br.a...@hotmail.com>:
> Philip
>
> Eu não sei que tipo de informação que você está buscando e onde você está
> buscando. Mas discordo de você que não há documentação em profundidade,
> preocupação com melhores práticas, etc.
>
> Seguem alguns links para te apoiar na sua busca e se você sentir falta de
> alguma coisa, deixe me saber:
>
--
2009/6/10 André Dias <br.a...@hotmail.com>:
> Quando você diz: "O MSDN não supre todas as dúvidas ou a documentação em
> geral foca no como e não no porque", você acaba limitando a ajuda que
> podemos te dar, já que você não foca no problema. Se você nos disser que
> tipo de informação você procurou e não encontrou, talvez possamos ajudá-lo
> melhor e quem sabe ajudar a melhorar essa imagem "ruim" que você possui em
> relação a documentação.
Ok, da próxima vez que encontrar este problema eu falo contigo.
> Sobre os Dispatchs, dei uma lida no wikipedia e podemos dizer que:
> 1) Polimorfismo = Single dispatch
> 2) Sobrecarga de métodos = multiple dispatch
>
> (ok, só mudaram o nome das coisas pra variar, mas vamos lá)
>
> mas ambos são static dispatch, já que são resolvidos em tempo de compilação.
Er... não. Citando a Wikipedia (que não é a melhor fonte mas é a mais
acessível):
"Dynamic dispatch is needed when multiple classes contain different
implementations of the same method foo(). If the class of an object x
is not known at compile-time, then when x.foo() is called, the program
must decide at runtime which implementation of foo() to invoke, based
on the runtime type of object x. This case is known as single dispatch
because an implementation is chosen based on a single type—that of the
type of the instance. Single dispatch is supported by many
object-oriented languages, including statically typed languages such
as C++ and Java, and dynamically typed languages such as Smalltalk and
Objective-C."
Single dispatch e multiple dispatch são, como o parágrafo acima
afirma, casos de dynamic dispatch.
> E se pra ser dinamico precisa ser resolvido em tempo de execução, porque é
> errado afirmar que o C# implementa dynamic dispatch através de Reflection ou
> a keyword dynamic do c# 4.0?
Não entendi este trecho.
> Aproveitando o e-mail, eu estava lendo as outras mensagens dessa thread e vi
> que vcs estavam discutindo linguagens 100% OO e lembrei de uma coisa bizarra
> que tinha no Java, não sei se isso ainda persiste. Que eram dois métodos que
> não existiam e nenhuma classe. Mas que se você os implementasse a JVM os
> chamava ... Se não me engano era algo como readObject() e writeObject() para
> customizar serialização, porém não faziam parte de nenhuma classe. Isso
> ainda existe?
Acho que por "não fazem parte de nenhuma classe" você quer dizer que
eles não são definidos por uma superclasse já que eles vão sim fazer
parte da classe que implementa Serializable. Eles não estão definidas
na interface porque são uma convenção que você deve seguir. Isto não
tem muita relação com Orientação a Objetos mas sim com a tipagem
estática de Java, que é bem fraca.
> Porém, tem um ponto que sinto muita falta do Java. São as checked
> Exceptions. Pra quem não conhece, toda vez que um código java lança uma
> exceção, o código que invoca este método é obrigado a tratá-la ou
> explicitamente transferir a responsabilidade para o chamador podendo chegar
> até o primeiro método que iniciou a cadeia. Isso é fantástico, pois se há
> alguma chance do seu código levantar uma exceção, se ela não for tratada
> você receberá um erro de compilação. Infelizmente isso foi sacrificado no c#
> pelo design da linguagem. Neste post
> http://www.artima.com/intv/handcuffs.html de 2003 (época em que ainda
> brincava com Java e tinha o James Gosling com ídolo) o Anders Hejlsberg
> explica o motivo.
>
> Vocês acham que checked exception seria util no dia a dia de vcs?
Interessante você falar isso. A maioria dos programadores experientes
em java que eu conheço odeia checked exceptions por serem burocráticas
e não trazerem benefícios.
[]s
Já ficou claro no e-mail do Giovanni, vamos para a próxima.
>
>> Aproveitando o e-mail, eu estava lendo as outras mensagens dessa thread e
>> vi
>> que vcs estavam discutindo linguagens 100% OO e lembrei de uma coisa
>> bizarra
>> que tinha no Java, não sei se isso ainda persiste. Que eram dois métodos
>> que
>> não existiam e nenhuma classe. Mas que se você os implementasse a JVM os
>> chamava ... Se não me engano era algo como readObject() e writeObject()
>> para
>> customizar serialização, porém não faziam parte de nenhuma classe. Isso
>> ainda existe?
>
> Acho que por "não fazem parte de nenhuma classe" você quer dizer que
> eles não são definidos por uma superclasse já que eles vão sim fazer
> parte da classe que implementa Serializable. Eles não estão definidas
> na interface porque são uma convenção que você deve seguir. Isto não
> tem muita relação com Orientação a Objetos mas sim com a tipagem
> estática de Java, que é bem fraca.
Ok, mas não é estranho todos os métodos do Java pertencerem a alguma classe
e apenas esses 2, não? Isso me cheira "gambiarra". No .net, além do atributo
[Serializable] que correponde Serializable do java, temos outros atributos
como [OnSerializing], [OnSerialized], [OnDeserializing], [OnDeserialized]
para serem utilizados em métodos que farão esse trabalho.
Pode parecer besteira, mas acho a implementação do .net muito mais clara
neste ponto!
>> Porém, tem um ponto que sinto muita falta do Java. São as checked
>> Exceptions. Pra quem não conhece, toda vez que um código java lança uma
>> exceção, o código que invoca este método é obrigado a tratá-la ou
>> explicitamente transferir a responsabilidade para o chamador podendo
>> chegar
>> até o primeiro método que iniciou a cadeia. Isso é fantástico, pois se há
>> alguma chance do seu código levantar uma exceção, se ela não for tratada
>> você receberá um erro de compilação. Infelizmente isso foi sacrificado no
>> c#
>> pelo design da linguagem. Neste post
>> http://www.artima.com/intv/handcuffs.html de 2003 (época em que ainda
>> brincava com Java e tinha o James Gosling com ídolo) o Anders Hejlsberg
>> explica o motivo.
>>
>> Vocês acham que checked exception seria util no dia a dia de vcs?
>
> Interessante você falar isso. A maioria dos programadores experientes
> em java que eu conheço odeia checked exceptions por serem burocráticas
> e não trazerem benefícios.
>
Eu também odiava quando programava em Java, depois com o Eclipse passei a
odiar menos já que o Eclipse colocava os blocos try/catch automáticos, e
depois que fui pro .NET fez uma falta. Sabe aquela coisa que só damos valor
quando perdemos? Talvez se aplique aqui :-)
2009/6/10 Giovanni Bassi <gig...@giggio.net>:
> Antes de mais nada, gostaria de deixar claro que entendo o que você chama de
> dynamic dispatch por outro nome: virtual dispatch.
Ok, entendi agora. Bom, Virtual Dispatch é apenas Dynamic Dispatch
usando uma v-table :)
http://en.wikipedia.org/wiki/Virtual_table
http://en.wikipedia.org/wiki/Virtual_function#Purpose
Um paper bem interessante (sobre C++ mas o conceito é o mesmo):
http://www.cs.ucsb.edu/~urs/oocsb/papers/oopsla96.pdf
Citação:
"Dynamic dispatch, i.e., the run-time selection of a target procedure
given a message name and the receiver type, is a central feature of
object-oriented languages. Compared to a subroutine call in a
procedural language, a message dispatch incurs two kinds of overhead:
adirect cost and anindirect cost. Thus the presence of dynamic
dispatch hinders optimization, and
consequently, the resulting program will run more slowly. [...]
2.1 Virtual function tables
C++ implements dynamic dispatch using virtual function tables (VFTs).
VFTs were first used by Simula [DM73] and today are the preferred C++
dispatch mechanism [ES90]. The basic idea of VFTs is to determine the
function address by indexing into a table of function pointers (the
VFT). Each class has its own VFT, and each instance contains a pointer
to the appropriateVFT."
Mas acho que no final concordamos que C# possui Virtual Dispatch, eu
só deixo claro que Virtual Dispatch é apenas uma implementação de
Dynamic Dispatch usando uma V-Table.
> A melhor forma de entender o virtual dispatch, é assumindo que cada método
> possui um "slot" associado a ele.
Isto é uma v-table ;)
> No entanto, é importante entender que o
> compilador sabe qual slot chamar, não sabendo apenas qual a implementação
> será utilizada, ou seja, não sabe o que há no slot, não sabe qual a
> referência deste slot, não sabe para qual método ele aponta. Por esse
> motivo, o compilador gera código (IL) para fazer essa verificação (o tal do
> "callvirt").
E isto é *exatamente* dynamic binding ;) Da wikipedia novamente:
"C++ uses a virtual table which defines the message to method mapping
for a given class. Instances of that type will then store a pointer to
this table as part of their instance data. This is complicated when
multiple inheritance is used. The virtual table in a C++ object cannot
be modified at run-time which limits the potential set of dispatch
targets to a finite set chosen at compile-time."
> Em uma chamada dinâmica, com o keyword "dynamic", como o exemplo a seguir:
> void Foo()
> {
> dynamic d = new D();
> d.M();
> }
> O compilador sequer sabe qual slot chamar. Isso fica claro naquele trecho
> grande de IL gerado no meu exemplo da mensagem anterior.
> Nesse caso, o slot de chamada só é descoberto em tempo de execução. O
> compilador nem sabe que o slot M deve ser chamado, porque não sabe o tipo
> com que está lidando e é impossível gerar um código para o slot de chamada.
Ele não sabe qual slot chamar porque não sabe qual o tipo do seu
objeto. A v-table é específica para um tipo (conf. documentação sobre
newslot no "Common Language Infrastructure" do ECMA) logo o runtime
vai ter que descobrir o tipo do objeto para poder chamar o método
correspondente -por isso a chamada a GetTypeFromHandle no seu exemplo
anterior.
Isto é exatamente o comportamento esperado em *tipagem* dinâmica, não
necessariamente dynamic dispatch -você pode uma linguagem que seja
estaticamente tipada mas com static binding apesar deste não ser o
caso de C#.
> E esse sim é o dynamic dispatch
> que eu estava mencionando desde o começo.
Bom, agora chegamos a um círculo interessante. Lá no início eu falei
que você estava misturando tipagem dinâmica com outros conceitos, você
falou que linguagens dinâmicas possuiam mais que tipagem dinâmica. No
fim das contas o que você me mostrou aqui é apenas tipagem dinâmica :)
Eu sei que havia dito que ia parar com a discussão mas acho que
estamos voltando ao rumo.
2009/6/10 André Dias <br.a...@hotmail.com>:
> Já ficou claro no e-mail do Giovanni, vamos para a próxima.
Na verdade não ficou não.
>> Acho que por "não fazem parte de nenhuma classe" você quer dizer que
>> eles não são definidos por uma superclasse já que eles vão sim fazer
>> parte da classe que implementa Serializable. Eles não estão definidas
>> na interface porque são uma convenção que você deve seguir. Isto não
>> tem muita relação com Orientação a Objetos mas sim com a tipagem
>> estática de Java, que é bem fraca.
>
> Ok, mas não é estranho todos os métodos do Java pertencerem a alguma classe
> e apenas esses 2, não? Isso me cheira "gambiarra". No .net, além do atributo
> [Serializable] que correponde Serializable do java, temos outros atributos
> como [OnSerializing], [OnSerialized], [OnDeserializing], [OnDeserialized]
> para serem utilizados em métodos que farão esse trabalho.
Er... como falei antes isso de "não pertencer a uma classe" não
procede já que eles vão pertencer à classe que os implementar. Como
também falei antes isso é uma convenção do framework de serialização.
E como também falei antes isso representa uma /bad smell/ no sistema
de tipos, não necessariamente em orientação a objetos.
> Pode parecer besteira, mas acho a implementação do .net muito mais clara
> neste ponto!
Ok.
Pra mim ficou, para falar a verdade eu nem lembro mais porque estamos
discutindo isso :-)
>>
>> Ok, mas não é estranho todos os métodos do Java pertencerem a alguma
>> classe
>> e apenas esses 2, não? Isso me cheira "gambiarra". No .net, além do
>> atributo
>> [Serializable] que correponde Serializable do java, temos outros
>> atributos
>> como [OnSerializing], [OnSerialized], [OnDeserializing], [OnDeserialized]
>> para serem utilizados em métodos que farão esse trabalho.
>
> Er... como falei antes isso de "não pertencer a uma classe" não
> procede já que eles vão pertencer à classe que os implementar. Como
> também falei antes isso é uma convenção do framework de serialização.
> E como também falei antes isso representa uma /bad smell/ no sistema
> de tipos, não necessariamente em orientação a objetos.
>
Errrr.... Se eu quero customizar o equals eu sobrescrevo o método, se quero
customizar o toString eu tenho que sobrescrever o método, Com esses dois não
tem que ser diferente. Neste ponto você pode chamar do conceito que quiser,
classificá-lo da forma que quiser, mas pra mim (Como eu falei antes),
continua sendo uma bela gambiarra.
2009/6/10 André Dias <br.a...@hotmail.com>:
> Errrr.... Se eu quero customizar o equals eu sobrescrevo o método, se quero
> customizar o toString eu tenho que sobrescrever o método, Com esses dois não
> tem que ser diferente. Neste ponto você pode chamar do conceito que quiser,
> classificá-lo da forma que quiser, mas pra mim (Como eu falei antes),
> continua sendo uma bela gambiarra.
Não exatamente. Diversos recursos em Java são baseados em convenções.
É a mesma coisa sobre chamar os controladores do ASP.Net MVC de
"XyzController".
Aliás, se o uso de convenções para você é gambiarra eu fico realmente
curioso sobre a sua opinião sobre Rails... :)
Sendo prático! Toda mulher tem dois seios. Se aparecer uma com apenas um
seio você também vai chamar de convenção? Eu não vou falar que a mulher é
uma gambiarra ou que está com defeito pq é muita sacanagem, mas posso
afirmar que não é normal. Assim como não é normal todos os métodos - 2 do
java pertencerem a alguma classe e essas duas criaturas não! Por que eles
são mais bonitos que os outros?
Sobre o Rails, o único contato que tive foi numa palestra do Akita. Eu achei
interessante, uma forma bem diferente da que desenvolvo hoje e apesar de
estar no meu radar, não é prioridade para esse ano.
Hummm .. Rails, convenção, mulheres com apenas 1 seio .... É ..acho que tá
na hora de ir dormir ... Boa noite!
2009/6/10 André Dias <br.a...@hotmail.com>:
> Sendo prático! Toda mulher tem dois seios. Se aparecer uma com apenas um
> seio você também vai chamar de convenção? Eu não vou falar que a mulher é
> uma gambiarra ou que está com defeito pq é muita sacanagem, mas posso
> afirmar que não é normal. Assim como não é normal todos os métodos - 2 do
> java pertencerem a alguma classe e essas duas criaturas não! Por que eles
> são mais bonitos que os outros?
Bom, eu já falei algumas dezenas de vezes que o método pertence a uma
classe e que é apenas uma convenção mas me parece que você está muito
mais interessado em atacar Java do que participar de um debate sadio
-do contrário não usaria comparações ridículas e de mau gosto ou
ficaria repetindo o mesmo argumento que já foi combatido.
Boa sorte com seus seios, com você eu parei por aqui. Não alimento trolls.
Esses métodos estão completamente fora do padrão e eu esperava uma resposta
mais relevante do que "É assim porque é assim". Talvez uma explicação porque
isso está diferente dos outros, porque não criaram uma interface
java.io.Serializable2 com esses métodos, etc. Você que é um cara que defende
tanto o "Porque" das coisas, não acha estranho aceitar uma resposta tão
simples e vaga como essa?
Sobre a brincadeira, eu fui para esse tom justamente para encerrar o assunto
porque eu vi que não íamos concordar nesse ponto, mas se ofendi você ou
algum outro membro da lista, peço minhas sinceras desculpas!
Alias, não estou atacando o java não. Como já disse, trabalhei um bom tempo
com ele e só mudei porque encontrei uma plataforma melhor (IMHO). E esse
ponto que citei é tão pequeno perto do java que nem vale a pena a discussão.
Só foi citado porque acho uma coisa bizarra ou como eu disse em e-mails
anteriores, uma bela gambiarra (IMHO tb).
Abraços
--
André Dias
SCJP - SCWCD - MCP - MCTS
http://blogs.msdn.com/andredias
http://twitter.com/andrediasbr
>
2009/6/11 Mauricio Aniche <maurici...@gmail.com>:
> Só para complementar, além de tipagem dinâmica, o C# apresenta outras
> características de linguagens dinâmicas. Você tem closures (se não me engano
> desde a versão 2.0, com delegates anônimos) e até higher-order functions
> (com o uso de predicates), por exemplo.
São funcionalidades bem impressionantes sim mas não estão relacionadas
com linguagens dinâmicas. Closures e higher-order functions são
funcionalidades ortogonais, encontradas em linguagems dinâmicas
(Ruby/Python/Lisp), estáticas(Haskell, F#, Ocaml) e mesmo de tipagem
fraca (Perl).
(note que ainda estou assumindo que "linguagem dinâmica" se refere à
tipagem dinâmica já que outras características citadas são ortogonais)
OK, we have seen quite a bit about the serialization process, now let's see some
more. What if you create a class whose superclass is serializable but you do not
want that new class to be serializable? You cannot unimplement an interface, so if
your superclass does implement Serializable
, your new class implements
it, too (assuming both rules listed above are met). To stop the automatic
serialization, you can once again use the private methods to just throw the
NotSerializableException
. Here is how that would be done:
10 private void writeObject(ObjectOutputStream out) throws IOException
20 {
30 throw new NotSerializableException("Not today!");
40 }
50 private void readObject(ObjectInputStream in) throws IOException
60 {
70 throw new NotSerializableException("Not today!");
80 }
Fonte: http://java.sun.com/developer/technicalArticles/Programming/serialization/