¿Es útil para los nuevos estudiantes aprender el lenguaje ceceo?
1.
Si organizamos los lenguajes de programación populares en el siguiente orden: Java, Perl, Python, Ruby: Java, Perl, Python, Ruby, encontrarás que cuanto más atrás, más se parece el lenguaje a Lisp. Python imita a Lisp, e incluso incluye muchas características que los piratas informáticos de Lisp considerarían errores de diseño. En cuanto a Ruby, si volvieras a 1975 y afirmaras que era un dialecto de Lisp, nadie se opondría. Los lenguajes de programación recién ahora están alcanzando el nivel que tenía Lisp en 1958.
II.
En 1958, John McCarthy diseñó el lenguaje Lisp. Creo que los lenguajes de programación más avanzados de la actualidad son implementaciones de su visión de 1958.
¿Cómo es esto posible? ¿No se está desarrollando rápidamente la tecnología informática? ¿Cómo podría la tecnología de 1958 ser más avanzada que la tecnología actual?
Déjame decirte por qué.
Esto se debe a que John McCarthy no pretendía originalmente que Lisp fuera un lenguaje de programación, al menos no lo que hoy llamaríamos un lenguaje de programación. Su intención original era simplemente crear un algoritmo teórico para definir una máquina de Turing de una manera más concisa.
Entonces, ¿por qué los lenguajes de programación de la década de 1950 no se han vuelto obsoletos a estas alturas? En pocas palabras, porque este lenguaje no es inherentemente una tecnología, sino matemáticas. Las matemáticas no están obsoletas. En lugar de vincular el lenguaje Lisp con el hardware de la década de 1950, una mejor analogía es el algoritmo Quicksort. Introducido en 1960, este algoritmo sigue siendo el método de clasificación de propósito general más rápido.
3.
El lenguaje Fortran también apareció en la década de 1950 y todavía se utiliza en la actualidad. Representa una dirección completamente diferente en el diseño de lenguajes; Lisp evolucionó inadvertidamente de pura teoría a un lenguaje de programación, mientras que Fortran fue diseñado como un lenguaje de programación desde el principio. Sin embargo, hoy pensamos en Lisp como un lenguaje de alto nivel y en Fortran como un lenguaje de nivel bastante bajo.
Cuando se creó Fortran en 1956, se llamó Fortran I y era muy diferente del lenguaje Fortran actual. Fortran I era en realidad lenguaje ensamblador más matemáticas y, en cierto modo, no era tan poderoso como los lenguajes ensambladores actuales. Por ejemplo, no admite subrutinas, solo estructuras de salto de rama (branching).
Lisp y Fortran representan las dos direcciones principales en el desarrollo de lenguajes de programación. El primero se basa en las matemáticas y el segundo en la arquitectura de hardware. Desde entonces, las dos direcciones han comenzado a acercarse. Lisp era poderoso cuando se diseñó por primera vez y durante las siguientes dos décadas continuó volviéndose más rápido. Los llamados lenguajes convencionales fueron diseñados para funcionar más rápido y luego tardaron más de cuarenta años en volverse gradualmente más poderosos.
Hoy en día, los lenguajes convencionales más avanzados apenas se están acercando al nivel de Lisp. Está cerca, pero aún no es tan poderoso como Lisp.
4.
El nacimiento del lenguaje Lisp contiene nueve ideas nuevas. Algunos de ellos los damos por sentado hoy, otros recién aparecían en otros lenguajes de alto nivel y dos todavía son exclusivos de Lisp. En orden de aceptación popular, son:
1. Estructuras condicionales (es decir, estructuras "si-entonces-si no"). Todo el mundo da esto por sentado ahora, pero Fortran I no tenía esta estructura, solo tenía estructuras Goto basadas en las instrucciones subyacentes de la máquina.
2. La función también es un tipo de datos.
En Lisp, una función es un tipo de datos, como un número entero o una cadena. Tiene su propia representación literal, que puede almacenarse en una variable o pasarse como parámetro. Tiene todas las características que debe tener un tipo de datos.
3. Recursión: Lisp es el primer lenguaje de alto nivel que soporta funciones recursivas.
4. Tipo dinámico de variables. En Lisp, todas las variables son en realidad punteros y los valores a los que apuntan son de un tipo diferente a las variables mismas. Copiar variables equivale a copiar punteros, no los datos a los que apuntan.
5. Mecanismo de recogida de basura.
6. Un programa se compone de expresiones; un programa Lisp es una colección de bloques de expresión, y cada bloque de expresión devuelve un valor. Esto contrasta con Fortran y la mayoría de los lenguajes posteriores, donde los programas se componen de expresiones y declaraciones.
La distinción entre expresiones y declaraciones es natural en Fortran I porque no admite el anidamiento de declaraciones. Entonces, si necesita calcular un valor en una fórmula matemática, la única forma de devolver ese valor es usar una expresión; no hay otras construcciones de sintaxis disponibles; de lo contrario, no podrá manipular el valor.
Más tarde, los lenguajes de programación más nuevos admitieron estructuras de bloques y, por supuesto, esta limitación ya no existía. Pero ya era demasiado tarde y la distinción entre expresiones y declaraciones se afianzó. Se expandió desde Fortran al idioma Algol, y luego a los idiomas posteriores de esos dos idiomas.
7. Tipo de símbolo. Los símbolos son en realidad punteros a cadenas almacenadas en la tabla hash. Entonces, para comparar la igualdad de dos símbolos, simplemente vea si sus punteros son iguales, sin comparar carácter por carácter.
8. El código utiliza representación de árbol (símbolos) de símbolos y constantes.
9. Todo el lenguaje está disponible en todo momento; Lisp realmente no distingue entre lectura, compilación y tiempo de ejecución. Puede compilar o ejecutar código en tiempo de lectura; puede leer o ejecutar código en tiempo de compilación y puede leer o compilar código en tiempo de ejecución;
Ejecutar código en tiempo de lectura le permite reescribir la sintaxis de Lisp; ejecutar código en tiempo de compilación es la base de las macros de Lisp; compilar código en tiempo de ejecución permite que Lisp sirva como un lenguaje de extensión en programas como Emacs; en Leer código en tiempo de ejecución le permite usar SAS entre programas; leer código en tiempo de ejecución le permite usar SAS entre programas. La lectura de código en tiempo de ejecución permite la comunicación entre programas utilizando expresiones S, un concepto que recientemente se ha "reinventado" con la llegada del formato XML.
5.
Cuando apareció por primera vez el lenguaje Lisp, su concepto era completamente diferente al de otros lenguajes de programación. La filosofía de diseño de este último estuvo determinada en gran medida por el hardware de finales de los años cincuenta. A medida que pasa el tiempo y se actualizan los lenguajes de programación populares, la filosofía de diseño del lenguaje se acerca gradualmente a Lisp.
Las ideas 1 a 5 han sido ampliamente aceptadas, la idea 6 está comenzando a aparecer en los lenguajes de programación convencionales y la idea 7 se ha implementado en el lenguaje Python, aunque no parece haber una sintaxis dedicada.
La idea 8 es probablemente la parte más interesante. Esta y la idea 9 pasaron a formar parte del lenguaje Lisp sólo por accidente, ya que no formaban parte de la concepción original de John McCarthy, sino que fueron añadidas por el propio alumno Steve Russell. Lo extraño de Lisp no es que tenga una sintaxis extraña, sino que no tiene ninguna sintaxis y los programas se expresan directamente en términos de árboles de análisis. En otros lenguajes, esta forma simplemente se genera detrás de escena mediante análisis, pero Lisp la trata directamente como una forma de expresión. Consta de listas, que son las estructuras de datos básicas de Lisp.
Resulta que expresar un lenguaje en sus propias estructuras de datos es muy poderoso. Las ideas 8 y 9 significan que puedes escribir un programa que pueda programarse a sí mismo. Esto puede sonar extraño, pero es muy común en el lenguaje Lisp.
La forma más común de hacer esto es usar macros.
La palabra "macro" tiene un significado diferente en Lisp que en otros lenguajes; una macro Lisp puede ser una abreviatura de una expresión o un compilador para un nuevo lenguaje. Si desea comprender verdaderamente Lisp, o si desea ampliar sus horizontes de programación, debe comprender las macros.
Hasta donde yo sé, las macros (definidas usando el lenguaje Lisp) siguen siendo exclusivas de Lisp. Una razón es que para poder utilizar macros es posible que tengas que hacer que tu lenguaje parezca tan arcaico como Lisp. Otra posible razón es que si desea agregar esta arma definitiva a su idioma, ya no puede afirmar haber inventado un nuevo idioma, solo un nuevo dialecto Lisp.
Lo digo en broma, pero es verdad. Si crea un nuevo lenguaje con características como car, cdr, cons, quote, cond, atom, eq, etc., y escribe funciones en listas, puede derivar todas las demás características de Lisp a partir de esa parte de características. De hecho, así es como se define el lenguaje Lisp, y John McCarthy diseñó el lenguaje con esta derivación en mente.
6.
Incluso si Lisp representa la dirección en la que se están acercando los lenguajes de programación convencionales actuales, ¿significa esto que deberías usarlo para programar?
¿Cuánto perderías si usaras un lenguaje menos potente? ¿No es a veces prudente no utilizar tecnología de punta? ¿No habla en sí mismo el hecho de que tanta gente utilice lenguajes de programación convencionales de las virtudes de esos lenguajes?
Por otro lado, para muchos proyectos no importa qué lenguaje de programación elijas; diferentes lenguajes harán el trabajo de todos modos. En términos generales, cuanto más exigente sea el proyecto, más potente será el lenguaje de programación. Sin embargo, existen innumerables proyectos que no tienen condiciones nada exigentes. La mayoría de las tareas de programación implican escribir pequeños programas y conectarlos con pegamento. Puede escribir estos pequeños programas en un lenguaje de programación con el que esté familiarizado o puede escribirlos en un lenguaje de biblioteca que sea más potente para su proyecto específico. Si sólo necesita pasar datos entre aplicaciones de Windows, Visual Basic satisfará sus necesidades.
¿Cuáles son entonces las ventajas de programación de Lisp?
7.
Cuanto más potente sea la función de programación del lenguaje, más corto será el programa que escribas (por supuesto, no se refiere al número de caracteres, sino a la sintaxis independiente). unidades).
La razón por la que el tamaño del código es importante es que el tiempo necesario para desarrollar un programa depende en gran medida de su duración. Si el mismo software dura tres veces más en un idioma que en otro, eso significa que dedicará el triple de tiempo a desarrollarlo. Incluso si contratas a más personas, no ayudará a acortar el tiempo de desarrollo, porque cuando el tamaño del equipo excede un cierto umbral, agregar más personas solo causará una pérdida neta, dijo Fred Brooks en su famoso libro "The Mythical Man-Month". Este fenómeno se describe en , y lo que vi y oí lo confirmó.
¿Cuánto más corto puede ser el programa si se utiliza Lisp? Por ejemplo, al comparar Lisp y C, la mayoría de las afirmaciones que escucho son que el código C es de 7 a 10 veces más largo que Lisp. Pero recientemente, hubo un artículo sobre ITA Software Company en la revista "New Architect", que mencionaba que "una línea de código Lisp equivale a 20 líneas de código C, ya que el artículo cita las palabras del presidente de ITA, supongo que esto". El número proviene de la práctica de programación de ITA. Si esto es cierto, entonces podemos creer esta afirmación. El software de ITA utiliza no sólo Lisp sino también mucho C y C++, por lo que esto es algo que hablan por experiencia.
Según los números anteriores, si compites con ITA y desarrollas software en C, ITA se desarrollará 20 veces más rápido que tú.
Si le lleva un año implementar una función, ITA le llevará menos de tres semanas. Por el contrario, si se tarda tres meses en desarrollar una nueva característica, le llevará cinco años implementarla.