lunes, 24 de agosto de 2009

Perl arcaico

[English translation]
Hace un par de dias me tocó atender un proveedor que vino a ofrecer sus servicios para el desarrollo de una aplicación web.
Como alguno de los participantes de la organización tuvo que manejar un imprevisto aproveché para iniciar un pequeña investigación durante la charla informal: "¿Que herramientas de desarrollo utilizan en su empresa?".
En un mundo ideal la respuesta hubiera sido: "Perl", pero me informaron que ellos trabajan principalmente en Python, aunque pueden trabajar en otros ambientes, incluyendo Perl.
Después de informarles que en la organización preferimos Perl para el desarrollo de nuestras aplicaciones, y después de un micro debate religioso, uno de ellos (Juan) concluyó:
En definitiva cualquier cosa que se puede hacer en un lenguaje se puede hacer en el otro, solo que en Perl la programación es más arcaica
en aquel momento casi me altero, pero en vista de que llegó el que faltaba y que lo importante era la reunión, me quedé tranquilo.
Ahora en retrospectiva me pregunto: ¿a qué se refería con eso de que Perl es arcaico?, tal vez, Juan se refería a Perl 1 (1987), que era una especie de Shell Script con grep, sed y awk incluido, incluso pudiera pensar que dijera eso hasta de Perl 4 (1991, un poco después de Python 1.0), sin embargo la era actual de Perl es 5 (1994) y en vista de la edad del personaje, creo que en realidad Juan no encontró una palabra que describiera todos los míticos defectos de Perl y terminó usando la palabra incorrecta.
Si Perl fuera arcaico, probablemente la programación orientada a objetos y la programación funcional también lo sean, sin embargo son las dos tecnologías con más impulso en la actualidad, y dado que incluso el sistema de orientación a objetos de Perl fue copiado de Python, asumiré que quiso decir alguna de las siguientes:
  1. Perl es feo
  2. Perl es desordenado
  3. Perl es ilegible
  4. Perl es incomprensible
Voy a responder brevemente a estos prejuicios que se han difundido ampliamente por Internet y para los cuales no hay un sustento real, y mucho menos después del renacimiento de Perl (del que hablaré en otro artículo).

Perl es feo

Como eso es cuestión de gustos, lo que es feo para algunos puede ser muy atractivo para otros. Pero suponiendo que Perl es uno de los lenguajes más feos, tiene características que lo hacen un lenguaje único para resolver una gran cantidad de problemas con facilidad.
Una de las características que hacen la sintaxis de Perl recargada (no necesariamente fea) son los sellos (sigils) que indican el tipo de cada variable, sin embargo esto facilita la extensibilidad del lenguaje y permite la interpolación en las cadenas, y cuando me refiero a que Perl es extensible quiero decir que se puede intervenir en el proceso de compilación para cambiar la sintaxis original, una característica de muy alto nivel que comparte con muy pocos lenguajes, y que es el fundamento de los lenguajes de dominio específico (o DSLs por sus siglas en inglés) que son muy útiles y populares. Perl ofrece al menos tres mecanismos diferentes para lograr este objetivo.
Otra característica es la práctica integración de las expresiones regulares en el lenguaje, logrando el uso extensivo de las mismas, lamentablemente dichas expresiones son feas sin importar el lenguaje. Tomemos como ejemplo el reconocimiento de una instrucción específica de LaTeX:

\begin{document}

En Perl se vería algo como:

if ( $latex =~ m/\\begin\{[a-z]+\}/ ) ...

En Python:

patron = re.compile(r'\\begin\{[a-z]+\}')
if
patron.match(latex):
...

En realidad ninguno de los dos es bonito, pero realmente en Perl es más sucinto y hasta más fácil de entender, y eso que no muestro lo tedioso que es usarlas en Java.
Finalmente está el bendito argumento sobre el estilo y todo aquella tontería de que el compilador obliga a indentar correctamente. Lo digo porque aún cuando es cierto que uno termina acostumbrándose, también es cierto que a veces es un fastidio y estorba, y en esos casos no hay remedio. Mas adelante hay un ejemplo de Python que no es fácil de formatear por lo inflexible de la sintaxis.
Cuando se requiere un estilo de código en particular, se usan herramientas de formateo, por ejemplo para C yo uso indent, y para Perl uso perltidy, últimamente el código que escribo suele estar en el siguiente estilo:

perltidy -l=99 -sbl

No importa como me entreguen el código o como lo transcriba yo mismo, porque lo puedo poner en mi estilo estándar con un solo comando, incluso antes de salvarlo (porque además uso vim).

Perl es desordenado

Los lenguajes no son desordenados, la gente lo es.
Sin embargo hay lenguajes que tienen más mecanismos que otros para organizar un proyecto, en particular Perl ofrece varias formas de organizar el código que se adaptan a muchas necesidades, que van desde la programación en una sola línea (de comandos), hasta la construcción de aplicaciones grandes y complejas.
El lenguaje permite la creación de módulos procedimentales con sus propios espacios de nombres, que incluso se pueden organizar en multiples archivos para ser cargados "on demand", bien enterprise, ¿cierto?.
Perl tiene un sistema básico de orientación a objetos que permite implementar OOP de muchas maneras diferentes, porque mientras muchos lenguajes solo hay una forma fija de manejar objetos, en Perl: "hay más de una forma de hacerlo".
Lo que no hace perl es obligar al programador a seguir una estructura determinada, sin importar si eso se adapta a las necesidades de un programa específico, porque si hiciera eso se parecería a Java.

Perl es ilegible

Esto es solo una combinación particular de los dos mitos que le preceden, aunque también se usa el argumento de que no se puede leer el código que se escribío hace 15 min. y eso bajo ciertas circunstancias es bueno, porque permite escribir programas rápidamente aunque sean sucios, después de todo nadie quiere ponerse a diseñar y documentar siguiendo los principios de ingeniería de software para comprender el último programa que escribí hace unas horas, únicamente porque necesitaba una pista sobre la frecuencia de aparición de los caracteres en una docena de archivos:

perl -MYAML -ne '$c{$_}++for split//;END{print Dump\%c}' datos.txt

Es más fácil escribirlo nuevamente que intentar comprenderlo, claro que el programa es una tontería en Perl porque tiene ciertas construcciones mágicas, pero no intenten algo así con otro lenguaje, porque su mejor escenario es lograr que funciona, pero garantizo que va a ser mucho más largo y difícil.
Sin embargo Perl también permite escribir el código mas bonito si eso fuera lo necesario:

use YAML;
use IO::File;
use strict;

my %cuentas;
my $fd = new IO::File $ARGV[0], "r";
while ( my $line = readline($fd) ) {
    for my $letra ( split( //, $line ) ) {
        $cuentas{$letra}++;
    }
}
print YAML::Dump( \%cuentas )
Estoy seguro de que no es muy difícil para un programador de Python o Ruby comprender lo que hace ese código ¿o sí?, luego la cuestión no es que el lenguaje sea ilegible, sino la motivación para escribir el programa y en todo caso la inteligencia del programador para escribir código legible o fácilmente mantenible aún por compañeros poco experimentados.
Finalmente la menor de mis preocupaciones fue el formato del código, pues la mayoría del trabajo lo hace mi editor automáticamente, pero por si acaso también lo pase por perltidy para que vean lo bien formateado que queda.

Perl es incomprensible

¿Para quién?, por ejemplo, el japonés es incomprensible para mi, pero dudo que lo sea para la mayoría de la gente que vive en Tokio, de igual manera Perl es incomprensible para alguien que no este entrenado para comprenderlo. En la sección anterior di un ejemplo de que se puede trabajar en Perl escribiendo el código de manera tan clara como en Python o en Java.
Ciertamente hay mucho código Perl que es prácticamente incomprensible excepto para los gurúes del lenguaje, pero eso no significa que los programas deban escribirse de esa manera.
Lo que si es cierto es que la forma sucinta que permite ofuscar el código hace de perl, no solo un interpretador sino una herramienta de uso común en la línea de comandos y al mismo tiempo permite la expresión del ingenio y maestría en el dominio del lenguaje. Hay muy pocos lenguajes que permitan hacer los JAPHs como Perl.
La falacia aparece cuando se dicen cosas como: "Perl es maligno porque permite esas cosas", "En Python es imposible hacer programas incomprensibles", ¿ah si?, a ver quien entiende este programita en Python:

for n in range(12):
    exec("abcdefghijkl"[n]+"=lambda x=0,y=0: "+filter(
        lambda x:x not in "\n$\r","""(x*y#x/x!range(x,
y#x+y!b(1,1#d(e~,e~#d(f~,f~#c(e~,e~+d(g~,d(g~,g~))#"%4
d" % a(x,y#map(lambda y:i(x,y),h~#" ".join(j(x)#"\\n".
join(map(k,h~))""".replace("~","()").replace("#",")!")
        ).split("!")[n])
print l()
Y puedo buscar cosas mucho más feas en Java, lo que significa que se pueden escribir programas incomprensibles en cualquier lenguaje, y un novato probablemente lo pueda hacer simplemente aprovechando su ignorancia. Por ello la importancia del personal calificado sin importar cual sea el lenguaje.
Sin embargo no se aprovechará todo el potencial de los programadores a menos que el lenguaje provea mecanismos de abstracción del más alto nivel, y es en este caso que lenguajes como Java y PHP son bastante malos mientras Perl supera a Python y a Ruby con holgura, descalificando completamente cualquier posibilidad de catalogar a Perl como un lenguaje arcaico.
Perl puede ser tan corporativo como cualquier otro lenguaje, y dominar este lenguaje en una organización, supone una inversión donde el código se puede utilizar y reutilizar de muchas maneras: desde los administradores de sistemas hasta los desarrolladores, pasando por los administradores de base de datos, etc.; en soluciones que van desde una simple operación de línea de comandos hasta la programación de una gran aplicación corporativa.

3 comentarios:

  1. Excelente Post Mr MacLeod.

    btw, ese Juan, es Apostols ?

    Saludos.

    ResponderEliminar
  2. translate.google.com does an excellent job of rendering this through to english by the way - maybe worth sticking a link to the translated version at the top of your posts so people who're willing to accept the machine translation can get to it easily?

    I liked this post very much - it's a rather succinct dissection of the common complaints and the correct answers to them.

    -- mst

    ResponderEliminar
  3. Matt: Thanks for your comments, I think the link to google translation is indeed a nice feature, done.

    Nelson: No se trata de Apostols, pero no daré detalles para proteger a los inocentes.

    ResponderEliminar