
Filosofía rectora
1. Lenguajes de programación para las personas
Los lenguajes de programación son cómo las personas hablan con las computadoras. A la computadora le encantará comunicarse en cualquier lenguaje que no sea ambiguo. La razón por la que tenemos lenguajes de alto nivel es porque las personas no pueden lidiar con el lenguaje de máquina. La esencia de los lenguajes de programación es evitar que nuestro frágil cerebro humano se sobrecargue con una cantidad excesiva de detalles.
Los arquitectos saben que algunos problemas de diseño son más tangibles que otros. Algunos de los problemas de diseño más claros y abstractos son el diseño de puentes. En este caso, su trabajo es cubrir la distancia requerida utilizando la menor cantidad de material posible. En el otro extremo del espectro está el diseño de sillas. Los diseñadores de sillas deben dedicar su tiempo a reflexionar sobre los traseros humanos.
El desarrollo de software tiene una distinción similar. Diseñar algoritmos para enrutar datos a través de una red es un buen problema abstracto, como el diseño de puentes. Mientras que diseñar lenguajes de programación es similar a diseñar sillas: se debe lidiar con las debilidades humanas.
A la mayoría de nosotros nos cuesta reconocer esto. Diseñar sistemas matemáticos elegantes suena mucho más atractivo para muchos de nosotros que ceder a las debilidades humanas. El papel de la elegancia matemática es que cierta medida de elegancia hace que los programas sean más fáciles de entender. Pero la elegancia no lo es todo.
Y cuando digo que los lenguajes deben ser diseñados teniendo en cuenta las debilidades humanas, no me refiero a que los lenguajes deben ser diseñados para programadores ineficaces. De hecho, debes diseñar software para los mejores programadores, pero incluso los mejores programadores tienen su límite. No creo que a nadie le gustaría programar en un lenguaje donde todas las variables se designaran con la letra «x» con índices enteros.
2. Diseña para ti y para tus amigos
Si miras la historia de los lenguajes de programación, la mayoría de los mejores lenguajes fueron diseñados para ser utilizados por sus propios creadores, mientras que la mayoría de los peores fueron diseñados para otras personas.
Cuando los lenguajes se diseñan para otras personas, siempre es para un grupo específico: las personas no son tan inteligentes como los creadores del lenguaje. Así obtienes un lenguaje que te habla con condescendencia. Cobol es el ejemplo más destacado, pero la mayoría de los lenguajes están impregnados de este espíritu.
Esto no tiene nada que ver con qué tan de alto nivel es el lenguaje. C es suficientemente de bajo nivel, pero fue creado para ser utilizado por sus autores, por eso a los hackers les encanta.
El argumento a favor de diseñar lenguajes para programadores malos es que hay más programadores malos que buenos. Puede que eso sea cierto. Pero este pequeño número de buenos programadores escribe desproporcionadamente más software.
Me interesa la pregunta de cómo crear un lenguaje que agrade a los mejores hackers. Creo que esta pregunta es idéntica a la de cómo crear un buen lenguaje de programación, pero incluso si no lo es, al menos es una pregunta interesante.
3. Dale al programador tanto control como sea posible
Muchos lenguajes (especialmente aquellos creados para otras personas) se comportan como niñeras: intentan advertirte sobre cosas que creen que no te serán útiles. Yo sostengo la opinión opuesta: dale al programador tanto control como puedas.
Cuando estudié Lisp por primera vez, lo que más me gustó fue que hablábamos en igualdad de condiciones. En otros lenguajes que había estudiado hasta ese momento, había un lenguaje y había mi programa en ese lenguaje, y existían bastante separados. Pero en Lisp, las funciones y macros que escribí eran las mismas en las que estaba escrito el propio lenguaje. Podía reescribir el propio lenguaje si quería. Tenía el mismo atractivo que el software de código abierto.
4. La brevedad es hermana del talento.
La brevedad es subestimada e incluso despreciada. Pero si miras en el corazón de los hackers, verás que aman la brevedad. ¿Cuántas veces has escuchado a los hackers hablar con amor sobre cómo, digamos, en APL pueden hacer cosas asombrosas con solo un par de líneas de código? Creo que las personas realmente inteligentes realmente aprecian esto.
Creo que casi todo lo que permite que los programas sean más cortos es bueno. Debe haber muchas funciones de biblioteca, todo lo que pueda ser implícito debe serlo; la sintaxis debe ser más concisa; incluso los nombres de las entidades deben ser cortos.
Y no solo los programas deben ser cortos. Los manuales también deben ser breves. Una buena parte de los manuales está llena de explicaciones, advertencias, precauciones y casos especiales. Si necesitas acortar un manual, la mejor opción es corregir el lenguaje que requiere tantas explicaciones.
5. Reconocer qué es el hacking
A muchas personas les gustaría que el hacking fuera matemáticas o, al menos, algo parecido a las ciencias naturales. Creo que el hacking es más como la arquitectura. La arquitectura está relacionada con la física, en el sentido de que el arquitecto debe diseñar un edificio que no se caiga, pero el verdadero objetivo del arquitecto es crear un gran edificio, no hacer descubrimientos en el ámbito de la estática.
Lo que los hackers aman es crear grandes programas. Y creo que, al menos en nuestros propios pensamientos, debemos recordar que escribir programas excepcionales es maravilloso, incluso cuando este trabajo no se traduce fácilmente en la moneda intelectual habitual de las publicaciones científicas. Desde una perspectiva intelectual, no es menos importante desarrollar un lenguaje que los programadores amen y crear algo espantoso que encarne una idea sobre la cual puedes publicar un artículo.
Problemas abiertos
1. ¿Cómo organizar grandes bibliotecas?
Las bibliotecas se están convirtiendo en una parte importante de los lenguajes de programación. Se están volviendo tan grandes que puede ser peligroso. Si lleva más tiempo encontrar una función en la biblioteca que hace lo que necesitas que escribir esa función tú mismo, entonces todo el código no hace más que engrosar tu manual. (Los manuales de Symbolics fueron un ejemplo de esto.) Así que tendremos que resolver el problema de la organización de bibliotecas. Idealmente, deben ser diseñadas de tal manera que el programador pueda deducir qué función de la biblioteca es adecuada.
2. ¿Las personas realmente temen la sintaxis de prefijo?
Este es un problema abierto en el sentido de que he estado pensando en él durante varios años y aún no conozco la respuesta. La sintaxis de prefijo me parece completamente natural, quizás excepto su uso en matemáticas. Pero puede ser que gran parte de la impopularidad de Lisp se deba simplemente a su sintaxis poco familiar... ¿Vale la pena hacer algo al respecto si esto es cierto? Esa es otra pregunta.
3. ¿Qué necesitas para el software de servidor?
Creo que la mayoría de las aplicaciones que se escribirán en los próximos veinte años serán aplicaciones web, en el sentido de que los programas estarán ubicados en un servidor y se comunicarán contigo a través del navegador web. Y para escribir tales aplicaciones necesitamos nuevas herramientas.
Una de esas cosas es el soporte de un nuevo método para lanzar aplicaciones de servidor. En lugar de uno o dos grandes lanzamientos al año, como el software de escritorio, el software de servidor se lanzará en una serie de pequeños cambios. Puedes tener cinco o diez lanzamientos al día. Y todos siempre tendrán la última versión.
¿Sabes cómo diseñar programas para que sean mantenibles? El software de servidor debe ser diseñado para ser adaptable. Debes tener la capacidad de modificarlo fácilmente, o al menos entender qué significa un pequeño cambio y qué es importante.
Otra cosa que puede ser útil en el software de servidor es, de repente, la continuidad de la entrega. En una aplicación web puedes usar algo como , para obtener el efecto de las subprogramas en un mundo sin estado de sesiones web. Tal vez valga la pena la continuidad de la entrega si esta capacidad no resulta demasiado costosa.
4. ¿Qué nuevas abstracciones quedan por descubrir?
No estoy seguro de cuán razonable es esa esperanza, pero a título personal, me encantaría descubrir una nueva abstracción; algo que pueda tener tanta importancia como las funciones de primer nivel, la recursión o al menos los parámetros predeterminados. Tal vez sea un sueño inalcanzable. A menudo, estos aspectos no se revelan. Pero no pierdo la esperanza.
Secretos poco conocidos
1. Puedes usar cualquier lenguaje que desees
Antes, la creación de aplicaciones significaba desarrollar software de escritorio. En el software de escritorio, había una fuerte inclinación hacia la escritura de aplicaciones en el mismo lenguaje que el sistema operativo. Así, hace diez años, desarrollar software en general significaba escribir software en C. Con el tiempo, esa tradición ha evolucionado: las aplicaciones no tienen que ser escritas en lenguajes no convencionales. Y esta tradición se ha desarrollado tanto que incluso las personas no técnicas, como gerentes y capitalistas de riesgo, lo han aprendido.
El software de servidor destruye completamente este modelo. Con el software de servidor, puedes usar cualquier lenguaje que desees. Casi nadie lo entiende todavía (especialmente gerentes y capitalistas de riesgo). Pero algunos hackers lo comprenden, por eso hemos oído hablar de lenguajes indie como Perl y Python. No escuchamos sobre Perl y Python porque la gente los utiliza para escribir aplicaciones para Windows.
¿Qué significa esto para nosotros, las personas interesadas en el diseño de lenguajes de programación? Que hay una audiencia potencial para nuestro trabajo.
2. La velocidad proviene de los perfiles
Los desarrolladores de un lenguaje o, al menos, sus implementadores, disfrutan escribir compiladores que generan código rápido. Pero creo que eso no es lo que hace que los lenguajes sean rápidos para los usuarios. Knuth notó hace tiempo que la velocidad depende de unos pocos cuellos de botella. Y cualquiera que haya intentado acelerar un programa sabe que no puedes adivinar dónde está el cuello de botella. Un perfilador es la respuesta.
Los desarrolladores del lenguaje están abordando el problema incorrecto. Los usuarios no necesitan que los benchmarks se ejecuten rápidamente. Necesitan un lenguaje que pueda mostrar qué partes de su programa deben ser reescritas. En ese momento, la velocidad es crucial. Tal vez sería mejor que los implementadores del lenguaje dedicaran la mitad del tiempo que gastan en optimizar el compilador a escribir un buen perfilador.
3. Necesitas una aplicación que haga que tu lenguaje evolucione
Puede que no sea la verdad absoluta, pero parece que los mejores lenguajes han evolucionado junto con las aplicaciones en las que se usaron. C fue creado por personas que necesitaban programación de sistemas. Lisp fue desarrollado en parte para la diferenciación simbólica; McCarthy estaba tan ansioso por comenzar que empezó a escribir programas de diferenciación incluso en el primer documento sobre Lisp en 1960.
Esto es especialmente útil si tu aplicación resuelve algunos problemas nuevos. Esto impulsa a tu lenguaje a tener nuevas capacidades que los programadores necesitan. Personalmente, me interesa escribir un lenguaje que sea bueno para aplicaciones de servidor.
[Durante la discusión, Guy Steele también expresó esta idea, añadiendo que una aplicación no debería consistir en escribir un compilador para tu lenguaje, a menos que tu lenguaje esté destinado a escribir compiladores.]
4. El lenguaje debe ser adecuado para escribir programas desechables.
Sabes lo que significa un programa desechable: es cuando necesitas resolver rápidamente una tarea limitada. Supongo que si miras a tu alrededor, encontrarás muchos programas serios que comenzaron como desechables. No me sorprendería si la mayoría de los programas comenzaron como desechables. Así que si quieres crear un lenguaje que sea adecuado para escribir software en general, también debe ser adecuado para escribir programas desechables, porque esa es la etapa inicial de muchos programas.
5. La sintaxis está relacionada con la semántica
Tradicionalmente se considera que la sintaxis y la semántica son cosas muy distintas. Puede que suene chocante, pero no es así. Creo que lo que quieres obtener en tu programa está relacionado con cómo lo expresas.
Recientemente hablé con Robert Morris, y él mencionó que la sobrecarga de operadores es una gran ventaja para los lenguajes con sintaxis infija. En los lenguajes con sintaxis prefija, cualquier función que definas es, de hecho, un operador. Si quieres sumar un nuevo tipo de número que has inventado, puedes simplemente definir una nueva función para su suma. Si haces esto en un lenguaje con sintaxis infija, verás que hay una gran diferencia entre usar un operador sobrecargado y llamar a una función.
Ideas que regresan con el tiempo
1. Nuevos lenguajes de programación
Mirando hacia atrás a los años 70, estaba de moda desarrollar nuevos lenguajes de programación. Ahora no es así. Pero creo que el software de servidor volverá a poner de moda la creación de nuevos lenguajes. Con el software de servidor, puedes usar cualquier lenguaje que desees, así que si alguien crea un lenguaje que parece mejor que los demás, habrá personas dispuestas a usarlo.
2. Dividir el tiempo
Richard Kelsey presentó esta idea, cuyo momento ha vuelto, y la apoyo completamente. Mi conjetura (y la de Microsoft también) es que muchos cálculos se trasladarán de los escritorios a servidores remotos. En otras palabras, la división del tiempo ha vuelto. Creo que se necesitará soporte a nivel de lenguaje. Por ejemplo, Richard y Jonathan Reeves han trabajado mucho en la implementación de la planificación de procesos en Scheme 48.
3. Eficiencia
Recientemente, parecía que las computadoras ya eran lo suficientemente rápidas. Cada vez escuchamos más sobre código intermedio, que al menos para mí significa que tenemos potencia de sobra. Pero creo que con el software de servidor, no la tenemos. Alguien tendrá que pagar por servidores, sobre los cuales funciona el software, y el número de usuarios que el servidor puede soportar por máquina será el divisor de sus costos de capital.
Creo que la eficiencia será importante, al menos en los cuellos de botella de los cálculos. Esto será especialmente significativo para las operaciones de entrada y salida, porque las aplicaciones del servidor generan muchas de estas operaciones.
Al final, puede resultar que el bytecode no sea la solución. Sun y Microsoft parecen estar enfrentándose cara a cara en el campo del bytecode en este momento. Lo hacen porque el bytecode es un lugar conveniente para integrarse en el proceso, no porque el bytecode sea en sí mismo una buena idea. Podría ser que toda esta batalla pase desapercibida. Sería divertido.
Trampas y emboscadas
1. Clientes
Esto es solo una suposición, pero se trata de que solo ganarán aquellas aplicaciones que sean completamente del lado del servidor. Diseñar software que funcione bajo la suposición de que todos tendrán tu cliente es como crear una sociedad basada en la suposición de que todos serán honestos. Sería definitivamente conveniente, pero tendrías que conceder que eso nunca sucederá.
Creo que habrá un rápido aumento de dispositivos con acceso a la web, y se puede suponer que soportarán HTML básico y formularios. ¿Tienes un navegador en tu teléfono? ¿Estará tu teléfono en tu PalmPilot? ¿Tendrá tu blackberry una pantalla más grande? ¿Tendrás la capacidad de acceder a Internet desde tu gameboy? ¿Desde tu reloj? No lo sé. Y no tendré que averiguarlo si apuesto a que todo estará en el servidor. Simplemente es mucho más confiable tener toda la lógica en el servidor.
2. Programación orientada a objetos
Entiendo que esta es una afirmación controvertida, pero no creo que la OOP sea algo importante. Pienso que es una paráfrasis adecuada para aplicaciones específicas que necesitan estructuras de datos particulares, como sistemas de ventanas, simulaciones, sistemas CAD. Pero no entiendo por qué debería ser adecuada para todos los programas.
Creo que a la gente en grandes empresas le gusta la OOP, en parte, porque ofrece mucho de lo que parece trabajo. Lo que naturalmente podría representarse como, digamos, una lista de números enteros, ahora puede representarse como una clase con todo tipo de andamiajes, con ruido y alboroto.
Otra característica atractiva de la OOP es que los métodos te dan un efecto de funciones de primer nivel. Pero esto no es nuevo para los programadores en Lisp. Cuando tienes funciones de primer nivel genuinas, puedes simplemente usarlas de cualquier manera que se adapte a la tarea en cuestión, en lugar de forzar todo en un patrón de clases y métodos.
Creo que esto significa que, para el diseño de lenguajes, no deberías integrar la OOP demasiado profundamente. Quizás la respuesta esté en ofrecer cosas más generales y fundamentales, y permitir que las personas diseñen cualquier sistema de objetos en forma de bibliotecas.
3. Diseño por comité
Si tu lenguaje es diseñado por un comité, estás atrapado, y no solo por las razones que todos conocen. Todos saben que los comités tienden a crear un diseño de lenguaje torpe e inconsistente. Pero creo que el mayor peligro es que no asumen riesgos. Cuando hay una sola persona a cargo, ella asume riesgos que un comité nunca aceptaría.
¿Es necesario arriesgarse para crear un buen lenguaje? Muchas personas podrían sospechar que el diseño de un lenguaje es algo en lo que debes ceñirte bastante a la sabiduría tradicional. Puedo argumentar que no es así. En todo lo demás que hacen las personas, la recompensa es proporcional al riesgo. Entonces, ¿por qué debería ser diferente en el diseño de lenguajes?
Fuente: habr.com
