Y ya sé lo que dirás, mirando el título del artículo:
- ¿Quién eres? ¿Por qué te permites decir eso?
Te responderé enseguida para que no haya omisiones:
- He estado programando profesionalmente en PHP desde 2004, es decir, durante 16 años al momento de escribir este artículo, y sigo haciéndolo todos los días.
- He estado enseñando programación, incluido PHP, durante aproximadamente 10 años y durante este tiempo he liberado a varios miles de estudiantes
- Siempre he estado encantado con cada nueva versión de PHP que salió de la versión 5.0 a la 7.4 y siempre he sido partidario del enfoque "escribir en la última versión, probar en la siguiente"
Y, sin embargo, a pesar de todo lo anterior, no me gusta en qué se está convirtiendo PHP ahora y en lo que se convertirá pronto, literalmente este otoño.
Casi todos los RFC adoptados en PHP 8 me causan dolor y desconcierto. Y estoy dispuesto a explicar y defender mi posición.
Los conceptos básicos del lenguaje cambian
¿Cómo suele empezar el aprendizaje de un nuevo idioma? Valores, expresiones, variables y funciones. Asimismo, aprender PHP es el orden natural.
Cuando empezamos a revisar las funciones, llamo la atención especial de los estudiantes sobre el hecho de que en PHP el contexto de las funciones está cerrado, "sellado". Es muy simple y completamente lógico: solo necesita recordar claramente qué nombres ve la función: sus argumentos y sus variables internas.
Cuando llegamos a los conceptos básicos de POO y aprendemos sobre el concepto de "método", nos basamos en el concepto de función y agregamos un elemento más al contexto: $ this en métodos dinámicos. ¿Algo más está cambiando? No. Las funciones todavía están cerradas, su contexto deja de existir después de la llamada, nada fluye hacia la función desde el exterior y tampoco fluye nada fuera de ella.
Llegamos a las funciones anónimas, y aquí las reglas del juego tampoco cambian. ¿Argumentos? Si. Variables internas? Si. $ esto? Bien, solucionemos esta pregunta, de lo contrario tendremos que discutir una cosa extraña llamada "función anónima estática" :)
A continuación, agregamos el concepto de "cierre". Todo es lógico para él, también, una palabra clave separada, una lista final de variables del contexto de creación, los principios básicos no se violan. Y dado que el valor está cerrado, no el nombre, entonces todo está bien en general: las funciones continúan "selladas". Nada del exterior se filtrará, nada se derramará.
¿Sabes qué pasa después?
Y luego tenemos las funciones de flecha. Y lo rompe todo.
Me veo obligado a explicar que las funciones de flecha violan principios difíciles de aprender porque se encierran en TODO el contexto en el momento de su creación.
Ops.
Pero, ¿qué pasa con el principio de "estanqueidad"? Pero de cualquier manera, no les importó un comino por simplificar la escritura, ahorrando 6 caracteres - ahora tenemos "fn" en lugar de "función".
Malo. Inconsistente.
¿Crees que este es el único ejemplo? No importa como sea.
Haga una pregunta a cualquier novato: ¿con qué carácter comienzan los nombres en PHP? Eso es correcto, con el "$"
- nombres de variables
- nombres de propiedad de objeto
- nombres de propiedad de clase
- nombres de argumentos
- ¡incluso las "variables variables" también son "$"!
Es lógico Si. ¿Consecuentemente? Si. Solo necesita recordar las constantes que no necesitan $.
¿Qué tenemos ahora? Argumentos con nombre: wiki.php.net/rfc/named_params
array_fill(value: 50, num: 100, start_index: 0);
¿Dónde está el "dólar"? No.
Esto es un problema.
Ahora debe recordar que debe escribir "dólar" en la firma de la función, pero no cuando se llama. Y este es un problema gravísimo que viola el sistema integral del lenguaje. Esto es malo e inconsistente.
¿Para qué? Sí, solo porque alguien quería transferir azúcar de Python a PHP sin pensar. Sin embargo, Python usa al menos el mismo símbolo "=" para hacer coincidir el nombre y el valor, tanto en la asignación como en los argumentos nombrados, y ahora tendremos dos de ellos: el habitual "=" y ":" en la nueva construcción.
Casi todos los RFC discutidos para PHP 8 conllevan el mismo problema: una violación del sistema de lenguaje previamente establecido. Y eso es malo. Rompe la mente tanto para aquellos que han estado escribiendo en PHP durante mucho tiempo, como para aquellos que están empezando a aprenderlo.
Ver: (wiki.php.net/rfc/match_expression_v2 )
echo match (1) {
0 => 'Foo',
1 => 'Bar',
2 => 'Baz',
};
estas son nuevas expresiones de coincidencia. ¿Puede explicar por qué utilizan el símbolo "=>" y no el habitual cambio de mayúsculas y minúsculas ":"? Yo tampoco puedo.
Esto es nuevamente una violación de un sistema ya establecido. El símbolo "=>" siempre (antes de que la maldita flecha funcione, ¡ellos de nuevo!) Denotó el separador de un par clave-valor. Ahora también denota el separador de la lista de argumentos y el valor de retorno en la "flecha" y el carácter de selección en el operador de coincidencia.
Esto es malo. Esto es muy malo. Esto es muy inconsistente. Esto es incluso peor que la palabra clave estática, que tiene al menos tres significados fundamentalmente diferentes.
Ilegibilidad del lenguaje natural
Mostrar el texto nativo en inglés
SELECT *
FROM users
WHERE age>=18 AND name LIKE 'J%'
y él, si su coeficiente intelectual supera los 60, explicará fácilmente de qué se trata este texto y qué se hará en la implementación de este texto como programa.
Muestra a un genio que no esté familiarizado con JS el texto
const f = () => 42;
y no entenderá nada. ¿Constante? f son estos paréntesis? ¿Los paréntesis van a un número? ¿Qué es?
Siempre me ha alegrado que PHP esté lejos de sacrificar la legibilidad del código en aras de la brevedad. Me alegré de que estuviera lejos de JS, donde se abandonó el principio de legibilidad del código en favor de "escribir menos caracteres, nadie leerá este código de todos modos".
Ahora me di cuenta de que PHP 8 rompería el principio de legibilidad natural. Y, aparentemente, irrevocablemente.
Solo mira estos ejemplos:
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,
) {}
}
Ahora, en lugar de los argumentos del constructor, declaramos propiedades inmediatamente y establecemos sus valores a partir de los argumentos.
¿Adivina qué hay después de los signos "="? ¿Valores iniciales de propiedad? ¿O los valores predeterminados de los argumentos del constructor? Es imposible de adivinar. Descúbrelo leyendo el código también. Esto es malo. Otro lugar para aprender de memoria.
wiki.php.net/rfc/property_write_visibility
class User {
public:private int $id;
public:protected string $name;
}
¿Propiedad público-privada? ¿Seriamente? ¿Cómo entender a partir de este código que estamos hablando de una propiedad legible y una propiedad escribible?
wiki.php.net/rfc/conditional_break_continue_return
function divide($dividend, $divisor = null) {
return if ($divisor === null || $divisor === 0): 0;
return $dividend / $divisor;
}
En serio, ¿alguien necesita esto? ¿Alguien escribió durante años en PHP y sufrió por no poder escribir "return ... if" en lugar de "if ... return"? ¿Realmente necesitamos una nueva sintaxis de yoda para los banales if y return?
Demasiadas formas de hacer lo mismo
PHP siempre ha violado el famoso principio de "debe haber una y sólo una manera ..." Pero lo hizo de manera inteligente, poco a poco y razonablemente.
Ahora este principio ha sido pisoteado y destruido. Cada RFC que se acepta dice, "agreguemos otra forma de escribir si, porque he visto esto en Perl / Python / Ruby / Brainfuck!" - y otras justificaciones, excepto como "Vi", en general, no se da.
Que pasó:
if ($y == 0)
return 0;
if ($y == 0) {
return 0;
}
if ($y == 0):
return 0;
endif;
- hasta tres formas de grabar lo mismo. No muy bien, tienes que explicar: por qué hay tres, por qué no debes escribir código sin corchetes y por qué necesitas una sintaxis alternativa.
¡Pero esto no es suficiente! Espera un poco más y verás:
// -If
return if ($y == 0): 0;
Así es como se llamaron las funciones:
foo(bar($baz));
Verás esto pronto:
$baz |> 'bar' |> 'foo'
- brillante, ¿no? ¡Está claro de inmediato que se trata de una llamada a función!
Y todavía no he escrito nada sobre las funciones de flecha :)
Más, más formas de hacer lo que se ha hecho antes sin ningún problema:
- expresiones-coincidentes
- operador "? ->"
- dos sintaxis diferentes para el cierre
- loop + else
- constructores estáticos
- declaraciones de propiedad en los argumentos del constructor (!)
y mucho más, lo que solo hará que el código sea más difícil de leer y el idioma más difícil de aprender.
Salir
PHP está evolucionando. Este es un proceso importante que afecta a una gran cantidad de personas y afecta a toda la comunidad de programación.
Sin embargo, comienza a surgir la sensación de que el desarrollo va mal en algún lugar. Me temo que los cambios adoptados llevarán al lenguaje al hecho de que los programas en él serán cada vez más cortos y menos legibles, al hecho de que brindará más y más oportunidades para hacer lo mismo de diferentes maneras, y aprender todos estos métodos será cada vez lleva más tiempo.
No quiero ver un nuevo Perl en lugar de PHP en un año. ¿Y tu?