Eu não gosto do que o PHP se transforma





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ê?



All Articles