Loading...

CINCO PREGUNTAS SOBRE EL DISEÑO DE LENGUAJES

Original

May 2001

(Estas son algunas notas que tomé para una mesa redonda sobre el diseño de lenguajes de programación en el MIT el 10 de mayo de 2001.)

1. Los Lenguajes de Programación Son para las Personas.

Los lenguajes de programación son cómo las personas hablan con las computadoras. La computadora estaría igual de contenta hablando cualquier idioma que fuera inequívoco. La razón por la que tenemos lenguajes de alto nivel es porque las personas no pueden lidiar con el lenguaje de máquina. El punto de los lenguajes de programación es evitar que nuestros pobres y frágiles cerebros humanos sean abrumados por una masa de detalles.

Los arquitectos saben que algunos tipos de problemas de diseño son más personales que otros. Uno de los problemas de diseño más limpios y abstractos es el diseño de puentes. Ahí tu trabajo es en gran medida cuestión de abarcar una distancia determinada con el menor material posible. El otro extremo del espectro es el diseño de sillas. Los diseñadores de sillas tienen que pasar su tiempo pensando en los traseros humanos.

El software varía de la misma manera. Diseñar algoritmos para enrutar datos a través de una red es un problema agradable y abstracto, como diseñar puentes. Mientras que diseñar lenguajes de programación es como diseñar sillas: todo se trata de lidiar con las debilidades humanas.

La mayoría de nosotros odia reconocer esto. Diseñar sistemas de gran elegancia matemática suena mucho más atractivo para la mayoría de nosotros que complacer las debilidades humanas. Y hay un papel para la elegancia matemática: algunos tipos de elegancia hacen que los programas sean más fáciles de entender. Pero la elegancia no es un fin en sí misma.

Y cuando digo que los lenguajes deben diseñarse para adaptarse a las debilidades humanas, no quiero decir que los lenguajes deban diseñarse para malos programadores. De hecho, creo que debes diseñar para los mejores programadores, pero incluso los mejores programadores tienen limitaciones. No creo que a nadie le gustara programar en un lenguaje donde todas las variables fueran la letra x con subíndices enteros.

2. Diseña para Ti Mismo y Tus Amigos.

Si miras la historia de los lenguajes de programación, muchos de los mejores eran lenguajes diseñados para que sus propios autores los usaran, y muchos de los peores fueron diseñados para que otras personas los usaran.

Cuando los lenguajes están diseñados para otras personas, siempre es un grupo específico de otras personas: personas no tan inteligentes como el diseñador del lenguaje. Así que obtienes un lenguaje que te habla desde arriba. Cobol es el caso más extremo, pero muchos lenguajes están impregnados por este espíritu.

No tiene nada que ver con cuán abstracto sea el lenguaje. C es bastante de bajo nivel, pero fue diseñado para que lo usaran sus autores, y esa es la razón por la que a los hackers les gusta.

El argumento para diseñar lenguajes para malos programadores es que hay más malos programadores que buenos programadores. Eso puede ser cierto. Pero esos pocos buenos programadores escriben una parte desproporcionadamente grande del software.

Me interesa la pregunta, ¿cómo se diseña un lenguaje que a los mejores hackers les gustará? Creo que esto es idéntico a la pregunta, ¿cómo se diseña un buen lenguaje de programación?, pero incluso si no lo es, es al menos una pregunta interesante.

3. Dale al Programador Tanto Control Como Sea Posible.

Muchos lenguajes (especialmente los que están diseñados para otras personas) tienen la actitud de una institutriz: intentan evitar que hagas cosas que creen que no son buenas para ti. Me gusta el enfoque opuesto: darle al programador tanto control como sea posible.

Cuando aprendí Lisp por primera vez, lo que más me gustó fue que me consideraba un socio igualitario. En los otros lenguajes que había aprendido hasta entonces, estaba el lenguaje y estaba mi programa, escrito en el lenguaje, y los dos estaban muy separados. Pero en Lisp las funciones y macros que escribí eran como las que componían el propio lenguaje. Podía reescribir el lenguaje si quería. Tenía el mismo atractivo que el software de código abierto.

4. Apunta a la Brevedad.

La brevedad está subestimada e incluso menospreciada. Pero si miras en el corazón de los hackers, verás que realmente la aman. ¿Cuántas veces has oído a los hackers hablar con cariño de cómo, digamos, en APL, podían hacer cosas increíbles con solo un par de líneas de código? Creo que cualquier cosa que las personas realmente inteligentes realmente amen vale la pena prestar atención.

Creo que casi cualquier cosa que puedas hacer para que los programas sean más cortos es bueno. Debería haber muchos funciones de biblioteca; cualquier cosa que pueda ser implícita debería ser; la sintaxis debe ser breve hasta el extremo; incluso los nombres de las cosas deben ser cortos.

Y no solo los programas deberían ser cortos. El manual también debe ser delgado. Una buena parte de los manuales se dedica a las aclaraciones y reservas y advertencias y casos especiales. Si te obligas a acortar el manual, en el mejor de los casos lo haces arreglando las cosas en el lenguaje que requirieron tanta explicación.

5. Admite Lo Que Es La Programación.

Muchas personas desean que la programación fuera matemáticas, o al menos algo parecido a una ciencia natural. Creo que la programación es más como la arquitectura. La arquitectura está relacionada con la física, en el sentido de que los arquitectos tienen que diseñar edificios que no se derrumben, pero el objetivo real de los arquitectos es hacer grandes edificios, no hacer descubrimientos sobre la estática.

Lo que a los hackers les gusta hacer es hacer grandes programas. Y creo que, al menos en nuestras propias mentes, tenemos que recordar que es algo admirable escribir grandes programas, incluso cuando este trabajo no se traduce fácilmente en la moneda intelectual convencional de los trabajos de investigación. Intelectualmente, es igual de valioso diseñar un lenguaje que a los programadores les encantará como diseñar un horrible que encarna alguna idea sobre la que puedes publicar un trabajo de investigación.

1. ¿Cómo Organizar Grandes Bibliotecas?

Las bibliotecas se están convirtiendo en un componente cada vez más importante de los lenguajes de programación. También se están haciendo más grandes, y esto puede ser peligroso. Si lleva más tiempo encontrar la función de biblioteca que hará lo que quieres que te lleve escribirla tú mismo, entonces todo ese código no está haciendo nada más que hacer tu manual grueso. (Los manuales de Symbolics fueron un caso en punto.) Así que creo que tendremos que trabajar en formas de organizar bibliotecas. Lo ideal sería diseñarlos para que el programador pudiera adivinar qué llamada de biblioteca haría lo correcto.

2. ¿La Gente Realmente Tiene Miedo de la Sintaxis de Prefijo?

Este es un problema abierto en el sentido de que me he preguntado por ello durante años y todavía no sé la respuesta. La sintaxis de prefijo me parece perfectamente natural a mí, excepto posiblemente para las matemáticas. Pero podría ser que mucho de la impopularidad de Lisp se deba simplemente a tener una sintaxis poco familiar. Si hacer algo al respecto, si es cierto, es otra pregunta.

3. ¿Qué Necesitas para el Software Basado en Servidor?

Creo que muchas de las nuevas aplicaciones más emocionantes que se escriben en los próximos veinte años serán aplicaciones basadas en la web, es decir, programas que se encuentran en el servidor y se comunican contigo a través de una web navegador. Y para escribir este tipo de programas, es posible que necesitemos algunos cosas nuevas.

Una cosa que necesitaremos es soporte para la nueva forma en que el servidor las aplicaciones se lanzan. En lugar de tener uno o dos lanzamientos grandes a año, como el software de escritorio, las aplicaciones basadas en servidor se lanzan como a serie de pequeños cambios. Es posible que tengas hasta cinco o diez versiones al día. Y como regla general, todos siempre usarán la última versión.

¿Sabes cómo puedes diseñar programas para que sean depurables? Bueno, el software basado en servidor también tiene que estar diseñado para ser cambiable. Tienes que poder cambiarlo fácilmente, o al menos para saber qué es un pequeño cambio y qué es un cambio trascendental.

Otra cosa que podría resultar útil para el servidor basado en el software, sorprendentemente, son las continuaciones. En el software basado en la web puedes usar algo como el estilo de paso de continuación para obtener el efecto de subrutinas en el inherentemente mundo sin estado de una web sesión. Tal vez valdría la pena tener continuaciones reales, si no fuera demasiado caro.

4. ¿Qué Nuevas Abstracciones Quedan por Descubrir?

No estoy seguro de qué tan razonable es esta esperanza, pero una cosa que realmente me gustaría hacer, personalmente, es descubrir una nueva abstracción, algo que haría tanto como tener funciones de primera clase o recursión o incluso parámetros de palabras clave. Este puede ser un imposible sueño. Estas cosas no se descubren con tanta frecuencia. Pero siempre estoy buscando.

1. Puedes Usar Cualquier Lenguaje Que Quieras.

Escribir aplicaciones los programas solían significar escribir software de escritorio. Y en el escritorio el software tiene una gran inclinación hacia escribir la aplicación en el mismo idioma que el sistema operativo. Y así hace diez años, escribir software prácticamente significaba escribir software en C. Eventualmente evolucionó una tradición: las aplicaciones no se deben escribir en lenguajes inusuales. Y esta tradición tuvo tanto tiempo para desarrollarse que las personas no técnicas como los gerentes y los capitalistas de riesgo también la aprendieron.

El software basado en servidor rompe con todo este modelo. Con el servidor basado en el software, puedes usar cualquier idioma que quieras. Casi nadie entiende esto todavía (especialmente los gerentes y los capitalistas de riesgo). Unos pocos hackers lo entienden, y esa es la razón por la que incluso escuchamos sobre nuevos lenguajes independientes como Perl y Python. No estamos escuchando sobre Perl y Python porque la gente los usa para escribir Windows aplicaciones.

Lo que esto significa para nosotros, como personas interesadas en diseñar lenguajes de programación, es que ahora potencialmente hay una audiencia real para nuestro trabajo.

2. La Velocidad Proviene de los Perfiles.

Los diseñadores de lenguajes, o al menos los implementadores de lenguajes, les gusta escribir compiladores que generen rápidos código. Pero no creo que esto sea lo que hace que los lenguajes sean rápidos para los usuarios. Knuth señaló hace mucho tiempo que la velocidad solo importa en unos pocos puntos críticos cuellos de botella. Y cualquiera que lo haya probado sabe que no puedes adivinar dónde están estos cuellos de botella. Los perfiladores son la respuesta.

Los diseñadores de lenguajes están resolviendo el problema equivocado. Los usuarios no necesitan puntos de referencia para que se ejecuten rápido. Lo que necesitan es un lenguaje que pueda mostrarles qué partes de sus propios programas necesitan ser reescritas. Eso es de dónde viene la velocidad en la práctica. Así que tal vez sería una red ganar si los implementadores de lenguaje se tomaran la mitad del tiempo que se hubieran pasado haciendo optimizaciones del compilador y se lo dedicaran a escribir a buen perfilador en su lugar.

3. Necesitas una Aplicación para Impulsar el Diseño de un Lenguaje.

Esto puede que no sea una regla absoluta, pero parece que los mejores lenguajes todos evolucionaron junto con alguna aplicación que estaban siendo utilizados para escribir. C fue escrito por personas que lo necesitaban para la programación de sistemas. Lisp fue desarrollado en parte para hacer diferenciación simbólica, y McCarthy estaba tan ansioso por comenzar que estaba escribiendo diferenciación programas incluso en el primer artículo sobre Lisp, en 1960.

Es especialmente bueno si tu aplicación resuelve algún problema nuevo. Eso tenderá a impulsar tu lenguaje a tener nuevas características que los programadores necesitan. Personalmente, estoy interesado en escribir un lenguaje que sea bueno para escribir aplicaciones basadas en servidor.

[Durante el panel, Guy Steele también hizo este punto, con el sugerencia adicional de que la aplicación no debe consistir en escribir el compilador para tu lenguaje, a menos que tu lenguaje esté destinado a escribir compiladores.]

4. Un Lenguaje Tiene Que Ser Bueno para Escribir Programas Desechables.

Sabes lo que es un programa desechable: algo que escribes rápidamente para alguna tarea limitada. Creo que si miraras a tu alrededor encontrarías que muchos programas grandes y serios comenzaron como programas desechables. Yo no me sorprendería si la mayoría de los programas comenzaran como desechables programas. Y así, si quieres hacer un lenguaje que sea bueno para escribir software en general, tiene que ser bueno para escribir programas desechables, porque esa es la etapa larvaria de la mayor parte del software.

5. La Sintaxis Está Conectada a la Semántica.

Es tradicional pensar en la sintaxis y la semántica como algo completamente separado. Esto sonará impactante, pero puede que no lo sean. Creo que lo que quieres en tu lenguaje puede estar relacionado con cómo lo expresas.

Estaba hablando hace poco con Robert Morris, y él señaló que la sobrecarga de operadores es una victoria más grande en lenguajes con infijo sintaxis. En un lenguaje con sintaxis de prefijo, cualquier función que defines es efectivamente un operador. Si quieres definir una suma para un nuevo tipo de número que has creado, puedes simplemente definir una nueva función para sumarlos. Si haces eso en un lenguaje con sintaxis infija, hay una gran diferencia en la apariencia entre el uso de un operador sobrecargado y una llamada a función.

1. Nuevos Lenguajes de Programación.

En la década de 1970 estaba de moda diseñar nuevos lenguajes de programación. Recientemente no ha sido así. Pero creo que el software basado en servidor hará que los nuevos lenguajes vuelvan a estar de moda. Con el software basado en servidor, puedes usar cualquier lenguaje que quieras, así que si alguien diseña un lenguaje que realmente parezca mejor que otros que están disponibles, habrá gente que se arriesgue y lo use.

2. Tiempo Compartido.

Richard Kelsey dio esto como una idea cuyo tiempo ha llegado de nuevo en el último panel, y estoy completamente de acuerdo con él. Mi conjetura (y la conjetura de Microsoft, parece) es que gran parte de la informática se trasladará desde el escritorio a servidores remotos. En otras palabras, la multiprogramación está de vuelta. Y creo que tendrá que haber soporte para ello a nivel de lenguaje. Por ejemplo, sé que Richard y Jonathan Rees han hecho mucho trabajo implementando procesos programación dentro de Scheme 48.

3. Eficiencia.

Recientemente estaba empezando a parecer que las computadoras finalmente eran lo suficientemente rápidas. Cada vez más estábamos empezando a oír hablar de byte code, lo que al menos para mí implica que sentimos que tenemos ciclos de sobra. Pero no creo que lo haremos, con el servidor basado en el software. Alguien tendrá que pagar por los servidores que el software se ejecuta, y el número de usuarios que pueden soportar por máquina será el divisor de su costo de capital.

Así que creo que la eficiencia importará, al menos en los computacionales cuellos de botella. Será especialmente importante hacerlo rápido de E/S, porque las aplicaciones basadas en servidor hacen muchas E/S.

Puede que resulte que el byte code no es una victoria, al final. Sun y Microsoft parecen estar enfrentándose en una especie de batalla de los bytes códigos en este momento. Pero lo están haciendo porque el byte code es un lugar conveniente para insertarse en el proceso, no porque el byte code sea en sí mismo una buena idea. Puede que resulte que esto todo el campo de batalla se omite. Eso sería un poco divertido.

1. Clientes.

Esto es solo una conjetura, pero mi conjetura es que el modelo ganador para la mayoría de las aplicaciones será puramente basado en servidor. Diseñar software que funcione con la suposición de que todos tendrán tu cliente es como diseñar una sociedad con la suposición de que todos serán honestos. Ciertamente sería conveniente, pero tienes que asumir que nunca sucederá.

Creo que habrá una proliferación de dispositivos que tienen algún tipo de acceso web, y todo lo que podrás asumir sobre ellos es que pueden admitir html y formularios simples. ¿Tendrás un navegador en tu teléfono celular? ¿Habrá un teléfono en tu palm pilot? ¿Tu blackberry obtendrá una pantalla más grande? ¿Podrás navegar por la web en tu gameboy? ¿Tu reloj? No lo sé. Y no tengo que saber si apuesto a que todo esté en el servidor. Es mucho más robusto tener todo el cerebro en el servidor.

2. Programación Orientada a Objetos.

Me doy cuenta de que este es un punto controvertido, pero no creo que la programación orientada a objetos sea tan importante. Creo que es un buen modelo para ciertos tipos de aplicaciones que necesitan ese tipo específico de estructura de datos, como sistemas de ventanas, simulaciones y programas CAD. Pero no veo por qué debería ser el modelo para toda la programación.

Creo que parte de la razón por la que a la gente de las grandes empresas les gusta la programación orientada a objetos es porque produce mucho trabajo aparente. Algo que podría representarse naturalmente como, digamos, una lista de enteros, ahora puede representarse como una clase con todo tipo de andamios y ajetreo.

Otra atracción de la programación orientada a objetos es que los métodos te dan algo de el efecto de funciones de primera clase. Pero esto es vieja noticia para los programadores de Lisp. Cuando tienes funciones de primera clase reales, puedes simplemente usarlas de la manera que sea apropiada para la tarea en cuestión, en lugar de obligar a todo a un molde de clases y métodos.

Lo que esto significa para el diseño del lenguaje, creo, es que no debes construir la programación orientada a objetos demasiado profundamente. Tal vez el la respuesta es ofrecer cosas más generales y subyacentes, y dejar que la gente diseñe los sistemas de objetos que quieran como bibliotecas.

3. Diseño por Comité.

Tener tu lenguaje diseñado por un comité es una gran trampa, y no solo por las razones que todo el mundo conoce. Todos sabe que los comités tienden a producir diseños abultados e inconsistentes. Pero creo que un peligro mayor es que no se arriesguen. Cuando una persona está a cargo, puede asumir riesgos que un comité nunca aceptaría.

¿Es necesario asumir riesgos para diseñar un buen lenguaje, sin embargo? Mucha gente podría sospechar que el diseño de lenguajes es algo en lo que deberías seguir bastante cerca de la sabiduría convencional. Apuesto a que esto no es cierto. En todo lo demás que hace la gente, la recompensa es proporcional al riesgo. ¿Por qué el diseño de lenguajes debería ser diferente?