Executando verificação de segurança...
4

Por que eu não gosto da notação fn no PHP — uma opinião sobre clareza e legibilidade no código

Recentemente, gravei um vídeo no YouTube explicando por que eu prefiro escrever de forma mais clara, em vez de mais resumida. No vídeo, falo sobre como, no PHP, existem duas maneiras de criar funções anônimas: usando a palavra-chave function ou a notação resumida fn.

Veja o exemplo abaixo usando a forma tradicional com function:

$mult = function ($a, $b) use ($factor) {
    return ($a * $b) * $factor;
};

E agora o mesmo exemplo usando a forma resumida com fn:

$mult = fn($a, $b) => ($a * $b) * $factor;

Apesar de a segunda forma ser mais curta, eu prefiro a primeira, pois acredito que o uso explícito de function torna o código mais legível, principalmente para quem está começando a aprender PHP.

Além disso, o uso do use no primeiro exemplo deixa claro que a variável $factor está sendo importada de um escopo externo — algo que a notação fn faz de forma implícita, o que pode causar confusão.

Em resumo: escrever de forma mais clara e explícita ajuda a manter o código legível e compreensível, mesmo que isso signifique usar algumas linhas a mais.

Link, para o vídeo:
https://www.youtube.com/watch?v=ZGE-cfXGL9c

Carregando publicação patrocinada...
6

um exemplo real de onde fn é mais útil:

$user = User::query()
    ->when($id, fn ($query) => $query->where('id', $id))
    ->when($email, fn ($query) => $query->where('email', $email))
    ->when($document, fn ($query) => $query->where('document', $document))
    ->first();

ficou uma sintaxe limpa, fácil de entender

agora considere o seguinte código:

$user = User::query()
    ->when($id, function ($query) use ($id) {
        return $query->where('id', $id);
    })
    ->when($email, function ($query) use ($email) {
        return $query->where('email', $email);
    })
    ->when($document, function ($query) use ($document) {
        return $query->where('document', $document);
    })
    ->first();

Nesse caso ficou muito pior usando o function completo.

Usar ou não usar a funcionalidade depende muito mais de onde está sendo usada do que da funcionalidade em si.

Odeio if ternário ?:

mas é muito melhor fazer algo assim:

return (permissions.length > 0) ? "admin" : "user"

do que escrever o if completo.

Tudo depende do contexto

3

A forma resumida pode ser mais clara, não há dicotomia nisso. Linguagens de programação estão cheia de coisas mais curtas e que as pessoas se dão bem, nem COBOL é assim mais de escrever tudo no inglês mais verboso possível. Linguagens de programação usam muitos símbolos e abreviações, e a pessoa já sabe ou acaba se acostumando que fica natural ela ler aquilo bem.

Essa forma foi criada por gera menos ruído, e ruído deixa as coisas menos claras.

Existem algumas confusões que as pessoas fazem, tem até livro famoso que faz isso. Quer código limpo? Não siga o Clean Code, porque o livro ensina coisas ótimas, outras nem tanto, você tem que separar o joio do trigo, muitas vezes sem a experiência necessária, mas tudo o que esse livro ensina é fazer código cheio de complexidades e nada limpo. Não estou dizendo que essas complexidades não podem ser úteis em alguns cenários, mas ainda não é um código limpo, pelo menos o termo está errado.

É comum as livros e artigos serem escolhidos por marketing e não tecnicamente, por isso as pessoas passaram a ter pavor de goto, pelo título escolhido pelo publisher de um artigo famoso que não prega "nunca use goto", mas o titulo prega isso.

Clareza pode ser subjetiva. Eu penso o oposto estudando dezenas ou centenas de linguagens nos meus mais de 40 de profissão. Mas eu farei o que for definido pela equipe. ANtes de escolher oque fazer precisa manter consistência de código. E eu vou usar minha força para que o padrão da equipe seja o que eu acho mais conveniente. fn pra mim é explícita. Não ter um return é implícito, mas como eu aprendi matemática na escola a implicitude vem para ajudar a clareza.

Código demais não é bom. Por isso não gosto de muitas boas práticas que pregam, por exemplo user contador como nome de variável em vez de i. Isso é bem "errado" porque o segundo é algo que todo mundo está acostumado e fica mais fácil visualizar código mais curto. Códigos longos são mais difíceis de cognição.

Não é a toa que eu primeiro vídeo/artigo no projeto que estou criando será "A péssima prática de seguir boas práticas". Escolhi não só porque é minha palestra de maior sucesso, mas também porque eu preciso de cara mudar um pensamento recorrente das pessoas que atrapalham seu aprendizado. Por isso é bom até para os experientes, desde que eles não sejam teimosos. Quem você deve escutar? (Este é um clickbait/spoiler implícito). Veja mais no final.

Espero que isso ajude as pessoas refletirem com um pouco mais de profundidade sobre o assunto, por isso eu até sai um pouco do tema. Obrigado ao autor pela oportunidade.

S2


Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente (não vendo nada, é retribuição na minha aposentadoria) (links aqui).

1

Não sou do PHP, mas sempre usei linguagens verbosas como Java, Dart, C# e afins como linguagem principal de trabalho.

Uma coisa q aprendi é q isso q vc cita é apenas gosto pessoal. Tem gente q prefere simplificar, tem gente q prefere escrever por extenso. No final é tudo msm coisa (claro eles fazem a msm coisa). Então se alguém conhece bem o PHP, tanto faz pra ele, pq no final ele entende o q está escrito e é isso q importa. Se vc gosta de padronizar, defina isso no projeto, pois o q importa é o q foi decidido na criação e assim mantém uma qualidade de código padronizado.