Em um futuro próximo, novos recursos aparecerão na linguagem Java, que atualmente está sendo trabalhada nos projetos de Valhalla, Panamá e Loom. Expandir um idioma não é uma tarefa fácil, especialmente um idioma em que a ênfase está na compatibilidade com versões anteriores; portanto, para que sua integração ao Java ocorra sem problemas, os arquitetos de linguagem precisam resolver problemas fundamentais acumulados.
Ontem (8 de janeiro), Brian Goetz, trabalhando na Oracle como arquiteto de linguagem Java, publicou uma
carta “Precisamos de mais palavras-chave, capitão!”. Na lista de discussão
do Project Amber
. em que ele propôs uma maneira de resolver o problema de adicionar novas palavras-chave ao idioma. Como resultado, as palavras-chave podem aparecer no idioma como
não nulo ,
não final ,
eventualmente final e
esse retorno (uma lista completa está esperando por você no recorte no final da postagem).
Como no passado esse problema surgia pouco frequentemente no idioma, eles geralmente não pensavam muito sobre o assunto e “tentavam sair do pescoço o mais rápido possível”; devido às deficiências das abordagens existentes no futuro, sua aplicação será problemática e, nesse sentido, foi decidido trabalhar com antecedência. Solução proposta: tente expandir o conjunto de formas lexicais que podem ser usadas como palavras-chave: permita palavras-chave separadas por um hífen, que usará uma (ou mais) palavras-chave existentes ou um identificador reservado.
Nota importante: Brown observa que as novas palavras-chave são fornecidas apenas como um exemplo ilustrativo e que você não deve se concentrar nelas. No entanto, é óbvio que temos diante de nós uma demonstração bem pensada de como a sintaxe da linguagem pode mudar no futuro - na carta, o autor menciona que essa ideia ajudará a adicionar muitas construções desejáveis de linguagem ausentes ao Java.
Métodos "antigos"
Como você sabe, hoje na linguagem Java existem 50 palavras-chave (
palavras-chave ), que são proibidas de usar como identificadores de variáveis. Uma lista completa é fornecida
na especificação da linguagem JLS na seção 3.9 . Essa lista não mudou muito desde a primeira versão do idioma - apenas a
declaração foi adicionada na versão 4,
enum na 5 e
_ na 9. Além deles, também existem "identificadores reservados" -
true ,
false e
null - que se comportam de maneira semelhante às palavras-chave caminho.
Quando os desenvolvedores precisam adicionar uma nova palavra-chave ao idioma, precisam recorrer a um dos seguintes métodos.
- Transferência forçada de propriedade: pegamos as palavras que eram identificadores anteriores e as transformamos em palavras-chave (por exemplo, afirme ).
- Descarte: uma palavra-chave existente começa a ser usada de uma maneira que nunca deveria ser usada (um exemplo é o uso de padrão para valores de anotação ou métodos padrão).
- Fique sem ele: encontre uma maneira de usar sintaxe que não exija uma nova palavra-chave - por exemplo, use a interface para anotações em vez de anotação - ou abandone completamente o recurso.
- Criando visibilidade: crie a ilusão de palavras - chave sensíveis ao contexto usando conquistas linguísticas heróicas ( palavras-chave restritas, nomes de tipos reservados ).
Em princípio, qualquer um desses métodos geralmente pode ser aplicado, mas cada um deles tem suas desvantagens e, para uma séria extensão em larga escala da linguagem, esses métodos por si só claramente não são suficientes - para futuras inovações, será necessário eliminar a incapacidade de estender completamente a sintaxe da linguagem.
Adicionando novas palavras-chave
Existem os seguintes argumentos contra "apenas" pegar e adicionar novas palavras.
- Quanto mais conveniente e popular for a palavra-chave selecionada, mais frequentemente ela será encontrada no código-fonte dos programas, o que adicionará incompatibilidade à linguagem (por exemplo, quando a palavra assert aparecer no Java SE 1.4, todas as estruturas de teste deixarão de funcionar).
- O custo de eliminar essa incompatibilidade do código pelo desenvolvedor variará muito, de pequeno (renomeando uma variável local) a fatal (quando o método de interface ou o tipo público for invalidado).
- Palavras que os desenvolvedores de idiomas têm maior probabilidade de usar são identificadores populares (por exemplo, valor , var ou método );
- Se você escolher palavras que raramente são usadas no código-fonte e com as quais haverá menos colisões, você terá que usar construções como geralmente_but_not_always_final , que no idioma naturalmente seria desejável evitar.
- Se, no entanto, você recorrer à escolha de palavras raramente usadas, usar esse método com muita frequência não funcionará - quebrar a compatibilidade não é bom e não existem muitas combinações bem-sucedidas.
Reutilizando palavras-chave "antigas"
Sobre “apenas” continuar vivendo com essas palavras, há considerações.
- Os precedentes da reutilização de palavras-chave em diferentes contextos são encontrados em muitas linguagens de programação (um exemplo de Java é o uso de ( (ab) use )) final para as designações "não mutável", "não redefinido" e "não extensível").
- Às vezes, essa abordagem faz sentido e vem por si só, mas geralmente não é uma prioridade.
- Com o tempo, o conjunto de requisitos para um conjunto de palavras-chave se expande e pode chegar a um ponto engraçado - ninguém deseja usar final nulo em seu código.
- Se este último lhe pareceu um exagero, lembre-se de que, enquanto trabalhava no JEP 325, eles sugeriram seriamente o uso da nova construção de comutador para descrever o comutador com diferentes semânticas - se você continuar na mesma linha, depois de dez anos, podemos alcançar novo novo interruptor .
Como viver sem novas palavras-chave? É possível parar completamente de se envolver na evolução da linguagem, como alguns sugeriram. Mas isso não é sério e não se encaixa na opinião dos demais, pois há um interesse saudável nos novos recursos da linguagem pelos desenvolvedores.
Palavras-chave contextuais
Palavras-chave contextuais usadas para fornecer um significado específico no código, mas não são palavras reservadas (
usadas em C # ) à primeira vista, parecem ser a mesma "varinha mágica", mas aqui Brian apresenta sua própria visão sobre o uso delas, com base na prática ( por exemplo, implementações
var no Java 10, que não é uma palavra-chave, mas um
nome de tipo reservado ). Em troca da ilusão de adicionar novas palavras-chave sem precisar "quebrar" os programas existentes, obtemos maior complexidade e distorção no idioma.
Palavras-chave contextuais são difíceis para escritores de especificações, compiladores e IDEs. No caso de um ou dois casos especiais, isso não causa problemas, mas quando eles começam a ser usados em todos os lugares, isso se traduz em um custo muito mais alto de suporte ao código ou cauda de bugs.
Alguém poderia descartar isso - eles dizem que isso não é um problema dos usuários de idiomas, mas de seus criadores e daqueles que escrevem compiladores e IDEs. Mas, na realidade, todo mundo sofre. Para o IDE, isso pode ser um problema significativo: serão necessárias mais entradas para adivinhar o que o desenvolvedor está inserindo - uma palavra-chave ou identificador contextual. Como resultado, os usuários sofrem uma deterioração no trabalho de realce de sintaxe, preenchimento automático e recursos de refatoração.
Você pode usar esta ferramenta, mas faça-o com cuidado.
Distorção da língua
Parece que com os problemas que essas abordagens causam - sintaxe desajeitada, complicações desnecessárias da vida e bugs - em princípio, poderíamos aturar isso. Mas há outro problema não mais óbvio - as nuances do uso de palavras-chave levam ao fato de que o design da própria linguagem está distorcido.
Para desenvolvedores Java, escrever uma
interface em vez de
anotação é comum hoje em dia, mas todos concordam que o uso do termo amigável
anotação em vez de uma combinação de @ e a palavra-chave "old" seria muito mais lógico.
Outro exemplo: o conjunto de modificadores disponíveis (público, privado, estático, final etc.) não pode ser chamado de completo - não podemos dizer nada que
não seja final ou
não estático . Por sua vez, isso significa que você não pode criar recursos nos quais variáveis ou classes são
finais por padrão, ou membros são
estáticos por padrão, pois não há como indicar que gostaríamos de abandonar esse modificador.
Esse problema não é tão óbvio para quem usa a linguagem - mas os autores da própria linguagem, por causa de seu desejo de desenvolvê-la ainda mais, encontram-na constantemente, e todos temos que pagar por essas decisões (quando explicitamente, quando implicitamente).
A conclusão de todas as alternativas acima se sugere: precisamos de outra fonte de palavras-chave.
Solução proposta
Nos recursos experimentais da linguagem, uma sintaxe é usada para pré-designar novas palavras-chave, nas quais as próprias palavras-chave são precedidas por dois sublinhados (por exemplo, no protótipo
Projeto Valhalla , é
__ByValue ). O motivo desta decisão é compreensível - você precisa ressaltar que se trata de uma substituição temporária, pela qual no futuro precisará tomar uma decisão sobre a sintaxe final e, ao mesmo tempo, evitar facilmente conflitos com o código existente. Pode-se sugerir o uso de um formato semelhante para novas palavras-chave - começando com um ou dois sublinhados -, mas essa solução não pode ser chamada de bonita, pois, neste caso, teremos confusão com palavras-chave comuns e novas.
Portanto, propõe-se usar palavras-chave construídas usando um hífen, que usará uma ou mais palavras-chave “antigas” ou identificadores reservados.
Diferentemente
das palavras-chave restritas , essa abordagem criará muito menos problemas para análise, pois (daqui em diante referido como exemplo)
not-null não pode ser confundido com uma expressão de subtração, e um lexer sempre pode determinar se
ab é três tokens ou um. Graças a isso, novas oportunidades estão se abrindo para criarmos palavras-chave com menor probabilidade de entrar em conflito com o código-fonte existente ou entre si. Além disso, é muito mais provável que tenham nomes significativos, pois muito do que os criadores da linguagem desejam adicionar ao Java se baseia em construções de linguagem existentes - por exemplo,
não nulas .
Como exemplos de novas palavras-chave, são prováveis candidatos ao lugar de novas palavras-chave (lembro-me que, de acordo com o autor, no momento essa lista é meramente ilustrativa):
-
não nulo ;
-
não final ;
-
package-private (modificador do nível de acesso aos membros da classe por padrão, que atualmente não é indicado de forma alguma);
-
leitura pública (leitura pública, gravação privada);
-
verificado com nulo ;
-
tipo estático (o conceito necessário para
Valhalla ; denota estático em relação à especialização específica da classe, e não a própria classe);
-
valor padrão ;
-
eventualmente final (o que agora deve ser feito usando a anotação
Stable ),
-
semifinal (como alternativa ao
lacrado );
-
interruptor exaustivo ;
-
classe enum, classe de anotação e classe de registro (os autores da linguagem poderiam usar essas palavras-chave como uma alternativa ao
enum e à
interface , se tivessem essa oportunidade);
-
this-class (para descrever o literal da classe para a classe atual);
-
this-return (geralmente solicitado a adicionar uma maneira de marcar o criador de métodos / criador como retornando seu destinatário).
Certamente existem outras variantes de esquemas lexicais segundo as quais seria possível compor palavras-chave para que elas se sobreponham minimamente às que já foram escritas pelo código-fonte. O hífen proposto é legível o suficiente para carros e humanos.
Entende-se que essa abordagem não exclui a possibilidade de usá-la em conjunto com as que foram usadas anteriormente, mas será usada junto com elas.