E eu já sei o que você vai dizer, olhando o título do artigo:
- Quem é você? Por que você se permite dizer isso?
Vou responder na hora para que não haja omissões:
- Tenho programado profissionalmente em PHP desde 2004, ou seja, há 16 anos no momento em que este livro foi escrito, e continuo fazendo isso todos os dias.
- Tenho ensinado programação, incluindo PHP, por cerca de 10 anos e durante esse tempo liberei vários milhares de alunos
- Sempre fiquei encantado com cada nova versão do PHP que saiu dos tempos de 5.0 a 7.4 e sempre fui um adepto da abordagem "escreva na versão mais recente, teste na próxima"
E, no entanto, apesar de tudo isso, não gosto no que o PHP está se transformando agora e no que vai se transformar em breve, literalmente neste outono.
Quase toda RFC adotada no PHP 8 me causa dor e perplexidade. E estou pronto para explicar e defender minha posição.
Mudança de conceitos básicos de linguagem
Como geralmente começa o aprendizado de um novo idioma? Valores, expressões, variáveis e funções. Da mesma forma, aprender PHP é a ordem natural.
Quando começamos a percorrer as funções, chamo atenção especial dos alunos para o fato de que no PHP o contexto das funções é fechado, "selado". Isso é muito simples e completamente lógico - você só precisa lembrar claramente quais nomes a função vê: seus argumentos e suas variáveis internas.
Quando chegamos ao básico de OOP e aprendemos sobre o conceito de "método", contamos com o conceito de uma função e adicionamos mais um item ao contexto: $ this em métodos dinâmicos. Algo mais está mudando? Não. As funções ainda estão fechadas, seu contexto deixa de existir após a chamada, nada flui de fora para a função e nada sai dela.
Chegamos a funções anônimas - e aqui as regras do jogo também não mudam. Argumentos? Sim. Variáveis internas? Sim. $ this? OK, vamos contornar esta questão, caso contrário, temos que discutir uma coisa estranha chamada "função anônima estática" :)
Em seguida, adicionamos o conceito de "encerramento". Tudo é lógico com ele, também, uma palavra-chave separada, uma lista final de variáveis do contexto de criação, os princípios básicos não são violados. E dado que o valor está fechado, não o nome, então está tudo bem - as funções continuam a ser "seladas". Nada de fora vazará, nada vai vazar.
Você sabe o que acontece a seguir?
E então temos funções de seta. E isso quebra tudo.
Sou forçado a explicar que as funções das setas violam princípios difíceis de aprender porque elas se prendem a TODO o contexto no momento de sua criação.
Ops.
Mas e quanto ao princípio de "estanqueidade"? Mas de qualquer forma, eles não deram a mínima para simplificar a escrita, economizando 6 caracteres - agora temos "fn" ao invés de "função".
Mau. Inconsistente.
Você acha que este é o único exemplo? Não importa como seja.
Faça uma pergunta a qualquer novato - com que personagem os nomes começam no PHP? Isso mesmo, com o "$"
- nomes de variáveis
- nomes de propriedade de objeto
- nomes de propriedade de classe
- nomes de argumentos
- até mesmo "variáveis variáveis" também são "$"!
Isso é lógico? Sim. Consistentemente? Sim. Você só precisa se lembrar das constantes que não precisam de $.
O que nós temos agora? Argumentos nomeados: wiki.php.net/rfc/named_params
array_fill(value: 50, num: 100, start_index: 0);
Onde está o "dólar"? Não.
Isso é problema.
Agora você tem que lembrar que você precisa escrever "dólar" na assinatura da função, mas não quando chamada. E este é um problema muito sério que viola o sistema integral da linguagem. Isso é ruim e inconsistente.
Para quê? Sim, só porque alguém queria transferir açúcar de Python para PHP sem pensar. No entanto, Python usa pelo menos o mesmo símbolo "=" para combinar nome e valor, tanto na atribuição quanto nos argumentos nomeados, e agora teremos dois deles - o usual "=" e ":" na nova construção.
Quase todas as RFCs discutidas para o PHP 8 carregam o mesmo problema - uma violação do sistema de linguagem estabelecido anteriormente. E isso é ruim. Isso quebra a mente de quem já escreve em PHP há muito tempo e de quem está começando a aprendê-lo.
Vejo: (wiki.php.net/rfc/match_expression_v2 )
echo match (1) {
0 => 'Foo',
1 => 'Bar',
2 => 'Baz',
};
essas são novas expressões de correspondência. Você pode explicar por que o símbolo "=>" é usado neles, e não o caso de comutação usual ":"? Também não posso.
Novamente, isso é uma violação de um sistema já estabelecido. O símbolo "=>" sempre (antes das funções de seta maldita, eles novamente!) Denotou o separador de um par de valores-chave. Agora também denota o separador da lista de argumentos e o valor de retorno na "seta" e o caractere de seleção no operador de correspondência.
Isto é mau. Isso é muito ruim. Isso é altamente inconsistente. Isso é ainda pior do que a palavra-chave estática, que tem pelo menos três significados fundamentalmente diferentes.
Ilegibilidade de linguagem natural
Mostra o texto nativo em inglês
SELECT *
FROM users
WHERE age>=18 AND name LIKE 'J%'
e ele, se seu QI exceder 60, explicará facilmente do que trata este texto e o que será feito ao implementar este texto como um programa.
Mostre a um gênio não familiarizado com JS o texto
const f = () => 42;
e ele não vai entender nada. Constante? f são parênteses? Os parênteses vão para um número? O que é isso?
Sempre gostei de PHP estar longe de sacrificar a legibilidade do código por uma questão de brevidade. Fiquei feliz por estar longe de JS, onde o princípio da legibilidade do código foi abandonado em favor de "escreva menos caracteres, ninguém vai ler este código de qualquer maneira."
Agora eu percebi que o PHP 8 quebraria o princípio da legibilidade natural. E, aparentemente, irrevogavelmente.
Basta olhar para estes exemplos:
wiki.php.net/rfc/constructor_promotion
class Point {
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
Agora, em vez de argumentos do construtor, declaramos imediatamente as propriedades e definimos seus valores a partir dos argumentos.
Adivinhe o que vem depois dos sinais "="? Valores iniciais de propriedade? Ou os valores padrão dos argumentos do construtor? É impossível adivinhar. Descubra lendo o código - também. Isto é mau. Outro lugar para aprender de cor.
wiki.php.net/rfc/property_write_visibility
class User {
public:private int $id;
public:protected string $name;
}
Propriedade público-privada? Seriamente? Como entender a partir desse código que estamos falando de uma propriedade legível e uma propriedade gravável?
wiki.php.net/rfc/conditional_break_continue_return
function divide($dividend, $divisor = null) {
return if ($divisor === null || $divisor === 0): 0;
return $dividend / $divisor;
}
Sério, alguém precisa disso? Alguém escreveu por anos em PHP e sofreu por não ser capaz de escrever "return ... if" em vez de "if ... return"? Nós realmente precisamos de uma nova sintaxe yoda para o banal if e return?
Muitas maneiras de fazer a mesma coisa
PHP sempre violou o famoso princípio de "deve haver um e apenas um caminho ..." Mas o fez de forma inteligente, aos poucos e razoavelmente.
Agora, esse princípio foi pisoteado e destruído. Cada RFC que é aceito diz, "vamos adicionar outra maneira de escrever if, porque eu vi isso em Perl / Python / Ruby / Brainfuck!" - e outras justificativas, exceto como "eu vi", em geral, não é fornecido.
O que aconteceu:
if ($y == 0)
return 0;
if ($y == 0) {
return 0;
}
if ($y == 0):
return 0;
endif;
- até três maneiras de gravar a mesma coisa. Não muito bom, você tem que explicar: por que existem três deles, por que você não deve escrever código sem colchetes de operador e por que você precisa de uma sintaxe alternativa.
Mas isto não é o suficiente! Espere um pouco mais e você verá:
// -If
return if ($y == 0): 0;
É assim que as funções eram chamadas:
foo(bar($baz));
Em breve você verá isto:
$baz |> 'bar' |> 'foo'
- brilhante, não é? É imediatamente claro que esta é uma chamada de função!
E ainda não escrevi nada sobre as funções das setas :)
Mais, mais maneiras de fazer o que era feito antes sem problemas:
- expressões de correspondência
- operador "? ->"
- duas sintaxes diferentes para encerramento
- loop + mais
- construtores estáticos
- declarações de propriedade em argumentos do construtor (!)
e muito mais, o que apenas tornará o código mais difícil de ler e a linguagem mais difícil de aprender.
Resultado
O PHP está evoluindo. Este é um processo importante que afeta um grande número de pessoas e afeta toda a comunidade de programação.
No entanto, começa a surgir a sensação de que o desenvolvimento está indo para algum lugar errado. Receio que as mudanças adotadas levarão a linguagem ao fato de que os programas nela se tornarão mais curtos e menos legíveis, ao fato de que fornecerá mais e mais oportunidades de fazer a mesma coisa de maneiras diferentes, e aprender todos esses métodos será leva cada vez mais tempo.
Não quero ver um novo Perl no lugar do PHP em um ano. E você?