Por que os operadores nulos e seguros (por exemplo, "operador Elvis") foram rejeitados como parte do "Project Coin" do Java 7?

10

Um dos recursos propostos para o "Project Coin" do Java 7 foi o "operador Elvis". Um relatório de uma apresentação do JavaOne de 2009 no Project Coin descreveu-o da seguinte forma:

Um dos "pequenos recursos" abordados nesta apresentação é o chamado "operador Elvis", uma versão mais concisa do operador ternário. Percebo que estou perdendo alguns dos recursos do Groovy ao usar o Java tradicional e esse seria um operador que eu poderia usar nas duas linguagens se fosse adicionado. O operador "Elvis" é útil para especificar um valor padrão que pode ser usado quando a expressão avaliada é nula. Como o operador de navegação segura do Groovy, é uma maneira concisa de especificar como evitar nulos desnecessários. Eu escrevi anteriormente sobre como gosto de evitar a NullPointerException.

Enquanto outros aspectos do Project Coin foram finalmente implementados, este não foi. Por que o Elvis Operator foi finalmente rejeitado, apesar de ter sido apresentado no JavaOne como um provável candidato à inclusão?

Para deixar claro, estou perguntando especificamente sobre esse operador e o motivo pelo qual ele foi rejeitado como parte do "Project Coin" do Java 7, já que era considerado seriamente na época. Suspeito que existam listas de discussão ou outras onde os motivos da rejeição foram discutidos, mas não consegui encontrar nada. Se houver informações mais gerais sobre o motivo de não estar incluído em nenhuma versão do Java, isso é aceitável, mas não preferido.

Forja do Trovão
fonte
4
Mentes suspeitas?
Ewan
1
Provavelmente, porque suporta e incentiva o uso de nulos como valores legítimos e, mais fundamentalmente, é contrário aos princípios de OO, porque você verifica o tipo de um objeto antes de executar um método.
JacquesB
A menos que alguém desenterre documentos explícitos (e-mails, memorandos, transcrições) do processo de decisão ou seja um participante direto da decisão, não podemos realmente saber a resposta aqui. Por exemplo, a resposta de Robert é apenas especulação e considerações gerais sobre o design da linguagem, não uma razão factual e específica para a rejeição deste operador. Por conseguinte, estou a votar para encerrar esta questão com base em opiniões.
amon
1
@ amon: Eu admiti livremente que minha resposta foi especulação no início do meu post. No entanto, eu postei uma resposta de qualquer maneira, porque 1. Estou ensinando a pescar em vez de dar um peixe, e 2. Esta postagem pode ser usada como alvo para enganadores próximos, se jogarmos as cartas corretamente. A idéia por trás de uma resposta que fornece uma análise geral é desencorajar argumentos sem fim sobre decisões minuciosas de linguagem e ajudar outras pessoas a ter uma visão mais ampla dos problemas gerais.
Robert Harvey
@RobertHarvey Um alvo canônico de "Por que o idioma X não possui o recurso Y" seria conveniente, mas a pergunta em sua forma atual não parece adequada para isso. Se fosse editada para fazer essa pergunta geral (usando X = Java / Y = ?.como exemplo ), certamente seria muito ampla como uma pergunta comum, mas você teria uma boa resposta.
amon

Respostas:

15

Naturalmente, a melhor pessoa para fazer esta pergunta é alguém no Comitê Executivo do JCP, não nós. No entanto, isso não me impedirá de me envolver em alguma especulação ociosa.

A resposta para todas as perguntas "por que esse recurso não foi implementado" é sempre porque os benefícios não excederam os custos.

Eric Lippert (ex-membro da equipe de C #) diz que, para que um produto tenha um recurso, esse recurso deve ser:

  • pensado em primeiro lugar
  • desejado
  • projetado
  • Especificadas
  • implementado
  • testado
  • documentado
  • enviado aos clientes

Em outras palavras, deve haver muitas coisas importantes que devem acontecer antes que qualquer novo recurso da linguagem de programação possa ser realizado. Os custos são maiores do que você pensa que são.

Na equipe de C #, cada nova solicitação de recurso começa com uma pontuação de menos 100. Em seguida, a equipe avalia os benefícios e os custos, adicionando pontos para os benefícios e subtraindo pontos para os custos. Se a pontuação não ultrapassar zero, o recurso proposto será descartado sumariamente. Em outras palavras, o novo recurso deve fornecer um benefício atraente.

Mas o Elvis Operator transformou-o em C #. Então, por que não chegou ao Java?

Apesar de suas aparentes semelhanças, Java e C # têm filosofias de linguagem significativamente diferentes. Isso é evidenciado pelo fato de que os programas corporativos Java tendem a ser grandes coleções estruturais de arquitetura. A brevidade e a expressividade da linguagem são sacrificadas no altar da cerimônia e na facilidade de codificação. Os padrões de arquitetura de software conhecidos que todos na equipe de desenvolvimento podem reconhecer são preferidos às conveniências de linguagem.

Considere esta troca do Reddit :

O operador Elvis foi proposto para todas as versões do Java desde 7 e foi rejeitado todas as vezes. Linguagens diferentes caem em pontos diferentes ao longo do espectro, de "puro" a "pragmático", e as linguagens que implementam o operador Elvis tendem a estar mais próximas do final pragmático do espectro que o Java.

Se você tem uma equipe de mais de 15 anos em Java, desenvolvendo algum tipo de sistema de processamento de back-end altamente distribuído e simultâneo, provavelmente deseja um alto grau de rigor arquitetural.

No entanto, se você tem uma equipe de nível intermediário a médio, metade dos quais migrou do Visual Basic, e você está escrevendo um aplicativo Web do ASP.NET que geralmente executa operações CRUD ... pode ser um exagero projetar um monte de AbstractFactoryFactoryclasses para abstrair o fato de que você não tem controle sobre quais colunas são anuláveis ​​no banco de dados herdado de merda que você deve usar.

Essas profundas diferenças na filosofia da linguagem se estendem não apenas à maneira como as línguas são usadas, mas à maneira como o processo de design da linguagem é realizado. C # é uma linguagem ditadora benevolente . Para inserir um novo recurso no C #, você só precisa convencer uma pessoa: Anders Hejlsberg .

Java adota uma abordagem mais conservadora. Para inserir um novo recurso em Java, é necessário obter consenso de um consórcio de grandes fornecedores, como Oracle, IBM, HP, Fujitsu e Red Hat. Obviamente, esse processo será mais lento e apresentará uma barra mais alta para novos recursos de idioma.

A pergunta "por que o recurso x não foi implementado ..." sempre inclui implicitamente as palavras "... se é obviamente uma boa idéia?" Como demonstrei adequadamente aqui, a escolha nunca é tão simples.

Robert Harvey
fonte
8
sarcasmo: porque as classes AbstractFactoryFactory são um bom indicador do rigor arquitetônico, e não do inchaço do código. /sarcasmo.
Machado
2
@RobertHarvey Suas conclusões sobre o papel dos comitês no design da linguagem Java são muito simplistas. Embora exista realmente colaboração com a comunidade e com os parceiros do setor, a afirmação de que a linguagem Java é "projetada pelo comitê" é praticamente completamente incorreta e uma explicação terrível (embora tristemente, superficialmente crível) para a pergunta deste pôster.
Brian Goetz
5
A maioria das razões listadas anteriormente - todos os recursos de idioma são maiores do que se pensa, orçamentos finitos (de esforço, de mudança e de complexidade) - são precisos. E eu acrescentaria: não fazemos o recurso X porque pensamos que outros recursos Y e Z são melhores escolhas. Além disso, também adotamos uma abordagem mais conservadora do que outros idiomas, porque sabemos que cada recurso interage ou, em alguns casos, exclui outros recursos possíveis no futuro. Queremos que o Java permaneça vibrante e relevante em 20 anos, o que significa necessariamente não sobrecarregar todos os recursos que possam parecer legais agora.
Brian Goetz
1
@BrianGoetz: Como o problema parece ser a natureza pejorativa do termo "design por comitê" (você notará que eu não menosprezei o Java de nenhuma outra maneira), mudei ligeiramente minha resposta para remover o termo.
Robert Harvey
1
Costumava haver alguma rivalidade entre os designers de C # e Java. O C # foi considerado um roubo por designers Java (e com razão). Os delegados do C # foram rejeitados por "não serem orientados a objetos", mas o verdadeiro motivo foi porque eles apareceram no C # primeiro. É bom pensar que é apenas por razões racionais que alguns recursos são adicionados ou deixados de fora ... Duvido.
precisa