Scheme es un dialecto de la familia de lenguajes de programación Lisp . Scheme fue creado durante la década de 1970 en el Laboratorio de Ciencias de la Computación e Inteligencia Artificial del MIT (MIT CSAIL) y publicado por sus desarrolladores, Guy L. Steele y Gerald Jay Sussman , a través de una serie de memorandos conocidos como los Lambda Papers . Fue el primer dialecto de Lisp en elegir el ámbito léxico y el primero en requerir que las implementaciones realizaran la optimización de llamadas recursivas , lo que brindó un mayor soporte para la programación funcional y técnicas asociadas como los algoritmos recursivos. También fue uno de los primeros lenguajes de programación en admitir continuaciones de primera clase . Tuvo una influencia significativa en el esfuerzo que condujo al desarrollo de Common Lisp . [ 2 ]
El lenguaje Scheme está estandarizado en el estándar oficial del Instituto de Ingenieros Eléctricos y Electrónicos (IEEE) [ 3 ] y en un estándar de facto llamado Informe Revisado sobre el Lenguaje Algorítmico Scheme (R n RS). Un estándar ampliamente implementado es R5RS (1998). [ 4 ] El estándar de Scheme ratificado más recientemente es "R7RS-small" (2013). [ 5 ] El R6RS, más extenso y modular, fue ratificado en 2007. [ 6 ] Ambos descienden de R5RS; la línea de tiempo que se muestra a continuación refleja el orden cronológico de ratificación.
Historia
Orígenes
Scheme surgió en la década de 1970 como un intento de comprender el modelo de actores de Carl Hewitt , para lo cual Steele y Sussman escribieron un "pequeño intérprete de Lisp" usando Maclisp y luego "añadieron mecanismos para crear actores y enviar mensajes". [ 7 ] Scheme se llamó originalmente "Schemer", siguiendo la tradición de otros lenguajes derivados de Lisp como Planner o Conniver . El nombre actual surgió del uso que hicieron los autores del sistema operativo ITS , que limitaba los nombres de archivo a dos componentes de un máximo de seis caracteres cada uno. Actualmente, "Schemer" se usa comúnmente para referirse a un programador de Scheme.
R6RS
En el taller Scheme de 2003 se inició un nuevo proceso de estandarización del lenguaje, con el objetivo de elaborar un estándar R6RS en 2006. Este proceso rompió con el enfoque anterior de unanimidad de R n RS.
R6RS presenta un sistema de módulos estándar, lo que permite una separación entre el lenguaje principal y las bibliotecas . Se publicaron varios borradores de la especificación R6RS, siendo la versión final la R5.97RS. Una votación exitosa resultó en la ratificación del nuevo estándar, anunciado el 28 de agosto de 2007. [ 6 ]
Actualmente, las versiones más recientes de diversas implementaciones de Scheme [ 8 ] son compatibles con el estándar R6RS. Existe una implementación de referencia portátil de las bibliotecas con fases implícitas propuestas para R6RS, denominada psyntax, que se carga y se inicializa correctamente en varias implementaciones antiguas de Scheme. [ 9 ]
Una característica de R6RS es el descriptor de tipo de registro (RTD). Cuando se crea y utiliza un RTD, la representación del tipo de registro puede mostrar la disposición de la memoria. También calcula la máscara de bits del campo del objeto y las máscaras de bits del campo del objeto Scheme mutable, y ayuda al recolector de basura a saber qué hacer con los campos sin recorrer toda la lista de campos guardados en el RTD. El RTD permite a los usuarios ampliar el RTD básico para crear un nuevo sistema de registros. [ 10 ]
R6RS introduce numerosos cambios significativos en el lenguaje. [ 11 ] El código fuente ahora se especifica en Unicode , y un gran subconjunto de caracteres Unicode puede aparecer ahora en símbolos e identificadores de Scheme , y hay otros cambios menores en las reglas léxicas. Los datos de caracteres también se especifican ahora en Unicode. Muchos procedimientos estándar se han trasladado a las nuevas bibliotecas estándar, que a su vez forman una gran expansión del estándar, conteniendo procedimientos y formas sintácticas que antes no formaban parte del estándar. Se ha introducido un nuevo sistema de módulos, y los sistemas para el manejo de excepciones ahora están estandarizados. Syntax-rules se ha reemplazado por una facilidad de abstracción sintáctica más expresiva (syntax-case) que permite el uso de todo Scheme en el momento de la expansión de macros. Ahora se requiere que las implementaciones compatibles admitan la torre numérica completa de Scheme , y la semántica de los números se ha expandido, principalmente en la dirección de la compatibilidad con el estándar IEEE 754 para la representación numérica de punto flotante.
R7RS
El estándar R6RS ha causado controversia porque algunos lo ven como una desviación de la filosofía minimalista. [ 12 ] [ 13 ] En agosto de 2009, el Comité Directivo de Scheme, que supervisa el proceso de estandarización, anunció su intención de recomendar la división de Scheme en dos lenguajes: un lenguaje de programación moderno y extenso para programadores; y una versión reducida, un subconjunto de la versión extensa que conserva el minimalismo elogiado por educadores y usuarios ocasionales. [ 14 ] Se crearon dos grupos de trabajo para desarrollar estas dos nuevas versiones de Scheme. El sitio web del Proceso de Informes de Scheme contiene enlaces a los estatutos de los grupos de trabajo, las discusiones públicas y el sistema de seguimiento de incidencias.
El noveno borrador de R7RS (lenguaje breve) se publicó el 15 de abril de 2013. [ 15 ] La votación para ratificar este borrador concluyó el 20 de mayo de 2013, [ 16 ] y el informe final está disponible desde el 6 de agosto de 2013, donde se describe "el lenguaje 'breve' de ese esfuerzo: por lo tanto, no puede considerarse de forma aislada como el sucesor de R6RS". [ 5 ]
Características distintivas
Scheme es principalmente un lenguaje de programación funcional . Comparte muchas características con otros miembros de la familia de lenguajes de programación Lisp. La sintaxis de Scheme, muy sencilla, se basa en expresiones S , listas entre paréntesis en las que un operador de prefijo va seguido de sus argumentos. Por lo tanto, los programas Scheme consisten en secuencias de listas anidadas. Las listas también son la estructura de datos principal en Scheme, lo que da lugar a una estrecha equivalencia entre el código fuente y los formatos de datos ( homoiconicidad ). Los programas Scheme pueden crear y evaluar fácilmente fragmentos de código Scheme de forma dinámica.
Todos los dialectos de Lisp comparten la dependencia de las listas como estructuras de datos. Scheme hereda un amplio conjunto de primitivas para el procesamiento de listas, como cons`list`, ` carlist` ycdr `list`, de sus predecesores en Lisp. Scheme utiliza variables con tipado estricto pero dinámico y admite procedimientos de primera clase . Por lo tanto, los procedimientos pueden asignarse como valores a variables o pasarse como argumentos a otros procedimientos.
Esta sección se centra principalmente en las características innovadoras del lenguaje, incluidas aquellas que distinguen a Scheme de otros lenguajes Lisp. Salvo que se indique lo contrario, las descripciones de las características se basan en el estándar R5RS. En los ejemplos de esta sección, la notación "===> resultado" se utiliza para indicar el resultado de evaluar la expresión de la línea inmediatamente anterior. Esta es la misma convención que se usa en R5RS.
Minimalismo
Scheme es un lenguaje muy simple, mucho más fácil de implementar que muchos otros lenguajes de poder expresivo comparable . [ 17 ] Esta facilidad se debe al uso del cálculo lambda para derivar gran parte de la sintaxis del lenguaje a partir de formas más primitivas. Por ejemplo, de las 23 construcciones sintácticas basadas en expresiones s definidas en el estándar Scheme R5RS, 14 se clasifican como formas derivadas o de biblioteca, que pueden escribirse como macros que involucran formas más fundamentales, principalmente lambda. Como dice R5RS (§3.1): "La más fundamental de las construcciones de enlace de variables es la expresión lambda, porque todas las demás construcciones de enlace de variables pueden explicarse en términos de expresiones lambda". [ 4 ]
- Formas fundamentales : define, lambda, quote, if, define-syntax, let-syntax, letrec-syntax, syntax-rules, set!
- Formas derivadas : do, let, let*, letrec, cond, case, and, or, begin, named let, delay, unquote, unquote-splicing, quasiquote
Ejemplo: una macro para implementar letcomo una expresión que se utiliza lambdapara realizar las vinculaciones de variables.
( define-syntax let ( syntax-rules () (( let (( var expr ) ... ) body ... ) (( lambda ( var ... ) body ... ) expr ... ))))Por lo tanto, usar letcomo se definió anteriormente una implementación de Scheme reescribiría " (let ((a 1)(b 2)) (+ b a))" como " ((lambda (a b) (+ b a)) 1 2)", lo que reduce la tarea de la implementación a la de codificar instanciaciones de procedimientos.
En 1998, Sussman y Steele comentaron que el minimalismo de Scheme no era un objetivo de diseño consciente, sino más bien el resultado no intencionado del proceso de diseño. «En realidad, estábamos intentando construir algo complicado y descubrimos, por casualidad, que habíamos diseñado accidentalmente algo que cumplía todos nuestros objetivos, pero que era mucho más simple de lo que habíamos previsto... nos dimos cuenta de que el cálculo lambda —un formalismo pequeño y sencillo— podía servir como núcleo de un lenguaje de programación potente y expresivo». [ 7 ]
Alcance léxico
Al igual que la mayoría de los lenguajes de programación modernos y a diferencia de los primeros Lisp como Maclisp , Scheme tiene un ámbito léxico: todas las posibles asignaciones de variables en una unidad de programa se pueden analizar leyendo el texto de la unidad sin considerar los contextos en los que se puede llamar. Esto contrasta con el ámbito dinámico, característico de los primeros dialectos de Lisp, debido a los costos de procesamiento asociados con los métodos primitivos de sustitución textual utilizados para implementar algoritmos de ámbito léxico en los compiladores e intérpretes de la época. En esos Lisp, era perfectamente posible que una referencia a una variable libre dentro de un procedimiento se refiriera a asignaciones completamente distintas fuera del procedimiento, dependiendo del contexto de la llamada.
El impulso para incorporar el alcance léxico, que era un modelo de alcance inusual a principios de la década de 1970, en su nueva versión de Lisp, provino de los estudios de Sussman sobre ALGOL . Sugirió que los mecanismos de alcance léxico similares a ALGOL ayudarían a lograr su objetivo inicial de implementar el modelo de actor de Carl Hewitt en Lisp. [ 7 ]
Las ideas clave sobre cómo introducir el alcance léxico en un dialecto de Lisp se popularizaron en el artículo de Sussman y Steele de 1975 sobre Lambda, "Scheme: An Interpreter for Extended Lambda Calculus" [ 18 ] , donde adoptaron el concepto de cierre léxico (en la página 21), que había sido descrito en un memorando de IA en 1970 por Joel Moses , quien atribuyó la idea a Peter J. Landin . [ 19 ]
Cálculo lambda
La notación matemática de Alonzo Church , el cálculo lambda, ha inspirado el uso de "lambda" en Lisp como palabra clave para introducir un procedimiento, además de influir en el desarrollo de técnicas de programación funcional que implican el uso de funciones de orden superior en Lisp. Sin embargo, las primeras versiones de Lisp no eran expresiones adecuadas del cálculo lambda debido a su tratamiento de las variables libres . [ 7 ]
Un sistema lambda formal posee axiomas y una regla de cálculo completa. Resulta útil para el análisis mediante lógica y herramientas matemáticas. En este sistema, el cálculo puede considerarse una deducción direccional. La sintaxis del cálculo lambda sigue las expresiones recursivas de x, y, z, ..., paréntesis, espacios, el punto y el símbolo λ. [ 20 ] La función del cálculo lambda incluye: Primero, servir como punto de partida para una lógica matemática potente. Segundo, reducir la necesidad de que los programadores consideren los detalles de implementación, ya que puede utilizarse para imitar la evaluación automática. Finalmente, el cálculo lambda ha creado una metateoría sustancial. [ 21 ]
La introducción del alcance léxico resolvió el problema al establecer una equivalencia entre algunas formas de notación lambda y su expresión práctica en un lenguaje de programación funcional. Sussman y Steele demostraron que el nuevo lenguaje podía utilizarse para derivar elegantemente toda la semántica imperativa y declarativa de otros lenguajes de programación, incluidos ALGOL y Fortran , y el alcance dinámico de otros Lisp, utilizando expresiones lambda no como simples instanciaciones de procedimientos, sino como "estructuras de control y modificadores de entorno". [ 22 ] Introdujeron el estilo de paso de continuaciones junto con su primera descripción de Scheme en el primero de los Lambda Papers, y en artículos posteriores, procedieron a demostrar el gran potencial de este uso práctico del cálculo lambda.
Estructura de bloques
Scheme hereda su estructura de bloques de lenguajes estructurados en bloques anteriores, en particular ALGOL . En Scheme, los bloques se implementan mediante tres construcciones de enlace : let, let*y letrec. Por ejemplo, la siguiente construcción crea un bloque en el que un símbolo llamado varestá vinculado al número 10:
( define var "goose" ) ;; Cualquier referencia a var aquí se vinculará a "goose" ( let (( var 10 )) ;; Las declaraciones van aquí. Cualquier referencia a var aquí se vinculará a 10. ) ;; Cualquier referencia a var aquí se vinculará a "goose"Los bloques pueden anidarse para crear estructuras de bloques de complejidad arbitraria según las necesidades del programador. El uso de la estructuración por bloques para crear enlaces locales reduce el riesgo de colisión de espacios de nombres que podría producirse de otro modo.
Una variante de let, let*, permite que las vinculaciones hagan referencia a variables definidas anteriormente en la misma construcción, de la siguiente manera:
( let* (( var1 10 ) ( var2 ( + var1 12 ))) ;; Pero la definición de var1 no podía referirse a var2 )La otra variante letrecestá diseñada para permitir que los procedimientos recursivos mutuos se vinculen entre sí.
;; Cálculo de las secuencias masculinas y femeninas de Hofstadter como una lista de pares( define ( hofstadter-male-female n ) ( letrec (( female ( lambda ( n ) ( if ( = n 0 ) 1 ( - n ( male ( female ( - n 1 ))))))) ( male ( lambda ( n ) ( if ( = n 0 ) 0 ( - n ( female ( male ( - n 1 )))))))) ( let loop (( i 0 )) ( if ( > i n ) ' () ( cons ( cons ( female i ) ( male i )) ( loop ( + i 1 )))))))( hofstadter-hombre-mujer 8 )===> (( 1 . 0 ) ( 1 . 0 ) ( 2 . 1 ) ( 2 . 2 ) ( 3 . 2 ) ( 3 . 3 ) ( 4 . 4 ) ( 5 . 4 ) ( 5 . 5 ))(Consulte las secuencias masculinas y femeninas de Hofstadter para ver las definiciones utilizadas en este ejemplo).
Todos los procedimientos vinculados en un solo letrecpueden referirse entre sí por su nombre, así como a los valores de las variables definidas anteriormente en el mismo letrec, pero no pueden referirse a los valores definidos posteriormente en el mismo letrec.
Una variante de let`let`, la forma "let con nombre", tiene un identificador después de la letpalabra clave. Esto vincula las variables `let` al argumento de un procedimiento cuyo nombre es el identificador dado y cuyo cuerpo es el cuerpo de la forma `let`. El cuerpo se puede repetir tantas veces como se desee llamando al procedimiento. La forma `let con nombre` se usa ampliamente para implementar iteraciones.
Ejemplo: un contador simple
( let loop (( n 1 )) ( if ( > n 10 ) ' () ( cons n ( loop ( + n 1 )))))===> ( 1 2 3 4 5 6 7 8 9 10 )Al igual que cualquier procedimiento en Scheme, el procedimiento creado en el let con nombre es un objeto de primera clase.
Recursión de cola propia
Scheme tiene una construcción de iteración, dopero es más idiomático en Scheme usar recursión de cola para expresar la iteración . Las implementaciones de Scheme conformes al estándar deben optimizar las llamadas de cola para admitir un número ilimitado de llamadas de cola activas (R5RS sec. 3.5) [ 4 ] , una propiedad que el informe de Scheme describe como recursión de cola propiamente dicha , lo que hace seguro para los programadores de Scheme escribir algoritmos iterativos usando estructuras recursivas, que a veces son más intuitivas. Los procedimientos recursivos de cola y la forma con nombrelet brindan soporte para la iteración usando recursión de cola.
;; Creando una lista de cuadrados del 0 al 9: ;; Nota: loop es simplemente un símbolo arbitrario usado como etiqueta. Cualquier símbolo servirá.( define ( lista-de-cuadrados n ) ( let loop (( i n ) ( res ' ())) ( if ( < i 0 ) res ( loop ( - i 1 ) ( cons ( * i i ) res )))))( lista-de-cuadrados 9 ) ===> ( 0 1 4 9 16 25 36 49 64 81 )Continuaciones de primera clase
Las continuaciones en Scheme son objetos de primera clase . Scheme proporciona el procedimiento call-with-current-continuation(también conocido como call/cc) para capturar la continuación actual empaquetándola como un procedimiento de escape vinculado a un argumento formal en un procedimiento proporcionado por el programador. (R5RS sec. 6.4) [ 4 ] Las continuaciones de primera clase permiten al programador crear construcciones de control no locales como iteradores , corrutinas y retroceso .
Las continuaciones se pueden usar para emular el comportamiento de las sentencias de retorno en lenguajes de programación imperativos. La siguiente función find-first, dada la función funcy la lista lst, devuelve el primer elemento xde lsttal manera que (func x)devuelve verdadero.
( define ( find-first func lst ) ( call-with-current-continuation ( lambda ( return-immediately ) ( for-each ( lambda ( x ) ( if ( func x ) ( return-immediately x ))) lst ) #f )))( ¿Buscar el primer entero? ' ( 1/2 3/4 5.6 7 8/9 10 11 )) ===> 7 ( ¿ Buscar el primer cero? ' ( 1 2 3 4 )) ===> #fEl siguiente ejemplo, un rompecabezas típico de programador, muestra que Scheme puede manejar las continuaciones como objetos de primera clase, vinculándolas a variables y pasándolas como argumentos a los procedimientos.
( let* (( yin (( lambda ( cc ) ( display "@" ) cc ) ( call-with-current-continuation ( lambda ( c ) c )))) ( yang (( lambda ( cc ) ( display "*" ) cc ) ( call-with-current-continuation ( lambda ( c ) c ))))) ( yin yang ))Al ejecutarse, este código muestra una secuencia de conteo:@*@**@***@****@*****@******@*******@********...
Espacio de nombres compartido para procedimientos y variables
A diferencia de Common Lisp, en Scheme todos los datos y procedimientos comparten un espacio de nombres común, mientras que en Common Lisp las funciones y los datos tienen espacios de nombres separados, lo que permite que una función y una variable tengan el mismo nombre y requiere una notación especial para referirse a una función como un valor. Esto se conoce a veces como la distinción " Lisp-1 vs. Lisp-2 ", en referencia al espacio de nombres unificado de Scheme y los espacios de nombres separados de Common Lisp. [ 23 ]
En Scheme, las mismas primitivas que se usan para manipular y enlazar datos se pueden usar para enlazar procedimientos. No existe un equivalente a las primitivas de Common defunLisp #'.
;; Variable ligada a un número: ( define f 10 ) f ===> 10 ;; Mutación (alteración del valor ligado) ( set! f ( + f f 6 )) f ===> 26 ;; Asignación de un procedimiento a la misma variable: ( set! f ( lambda ( n ) ( + n 12 ))) ( f 6 ) ===> 18 ;; Asignación del resultado de una expresión a la misma variable: ( set! f ( f 1 )) f ===> 13 ;; Programación funcional: ( apply + ' ( 1 2 3 4 5 6 )) ===> 21 ( set! f ( lambda ( n ) ( + n 100 ))) ( map f ' ( 1 2 3 )) ===> ( 101 102 103 )Estándares de implementación
Esta subsección documenta las decisiones de diseño que se han tomado a lo largo de los años y que le han dado al proyecto un carácter particular, pero que no son el resultado directo del diseño original.
Torre numérica
Scheme especifica un conjunto relativamente completo de tipos de datos numéricos, incluidos los tipos complejos y racionales , que en Scheme se conoce como la torre numérica (R5RS sec. 6.2 [ 4 ] ). El estándar los trata como abstracciones y no obliga al implementador a utilizar ninguna representación interna en particular.
Los números pueden tener la cualidad de la exactitud. Un número exacto solo puede obtenerse mediante una secuencia de operaciones exactas que involucren otros números exactos; por lo tanto, la inexactitud es contagiosa. El estándar especifica que cualquier par de implementaciones debe producir resultados equivalentes para todas las operaciones que den como resultado números exactos.
El estándar R5RS especifica procedimientos exact->inexactque inexact->exactse pueden usar para cambiar la exactitud de un número. inexact->exactproduce "el número exacto que está numéricamente más cerca del argumento". exact->inexactproduce "el número inexacto que está numéricamente más cerca del argumento". El estándar R6RS omite estos procedimientos del informe principal, pero los especifica como procedimientos de compatibilidad R5RS en la biblioteca estándar (rnrs r5rs (6)).
En el estándar R5RS, las implementaciones de Scheme no están obligadas a implementar toda la torre numérica, pero deben implementar "un subconjunto coherente consistente con los propósitos de la implementación y el espíritu del lenguaje Scheme" (R5RS sec. 6.2.3). [ 4 ] El nuevo estándar R6RS sí requiere la implementación de toda la torre, y "objetos enteros exactos y objetos de números racionales exactos de tamaño y precisión prácticamente ilimitados, y la implementación de ciertos procedimientos... para que siempre devuelvan resultados exactos cuando se les proporcionan argumentos exactos" (R6RS sec. 3.4, sec. 11.7.1). [ 6 ]
Ejemplo 1: aritmética exacta en una implementación que admite números complejos racionales exactos.
;; Suma de tres números reales racionales y dos números complejos racionales ( definir x ( + 1/3 1/4 -1/5 -1/3i 405/50+2/3i )) x ===> 509/60+1/3i ;; Comprobar la exactitud. ( ¿ exacto? x ) ===> #tEjemplo 2: La misma aritmética en una implementación que no admite ni números racionales exactos ni números complejos, pero sí acepta números reales en notación racional.
;; Suma de cuatro números reales racionales ( define xr ( + 1/3 1/4 -1/5 405/50 )) ;; Suma de dos números reales racionales ( define xi ( + -1/3 2/3 )) xr ===> 8.48333333333333 xi ===> 0.333333333333333 ;; Comprobar la exactitud. ( exact? xr ) ===> #f ( exact? xi ) ===> #fAmbas implementaciones cumplen con el estándar R5RS, pero la segunda no cumple con el estándar R6RS porque no implementa la torre numérica completa.
Evaluación retrasada
El programa permite la evaluación diferida mediante el delayformulario y el procedimiento force.
( define a 10 ) ( define eval-aplus2 ( delay ( + a 2 ))) ( set! a 20 ) ( force eval-aplus2 ) ===> 22 ( define eval-aplus50 ( delay ( + a 50 ))) ( let (( a 8 )) ( force eval-aplus50 )) ===> 70 ( set! a 100 ) ( force eval-aplus2 ) ===> 22Se conserva el contexto léxico de la definición original de la promesa, y su valor también se conserva después del primer uso de la misma force. La promesa solo se evalúa una vez.
Estas primitivas, que producen o manejan valores conocidos como promesas , pueden usarse para implementar construcciones de evaluación perezosa avanzadas como flujos . [ 24 ]
En el estándar R6RS, estos ya no son primitivos, sino que se proporcionan como parte de la biblioteca de compatibilidad R5RS (rnrs r5rs (6)).
En R5RS, se proporciona una implementación sugerida de delayy force, implementando la promesa como un procedimiento sin argumentos (un thunk ) y utilizando memorización para asegurar que solo se evalúe una vez, independientemente del número de veces forceque se llame (R5RS sec. 6.4). [ 4 ]
SRFI 41 permite expresar secuencias finitas e infinitas con una economía extraordinaria. Por ejemplo, esta es una definición de la secuencia de Fibonacci utilizando las funciones definidas en SRFI 41: [ 24 ]
;; Definir la secuencia de Fibonacci: ( define fibs ( stream-cons 0 ( stream-cons 1 ( stream-map + fibs ( stream-cdr fibs ))))) ;; Calcular el centésimo número de la secuencia: ( stream-ref fibs 99 ) ===> 218922995834555169026Orden de evaluación de los argumentos procesales
La mayoría de los lenguajes Lisp especifican un orden de evaluación para los argumentos de los procedimientos. Scheme no lo hace. El orden de evaluación —incluido el orden en que se evalúa la expresión en la posición del operador— puede ser elegido por una implementación en cada llamada, y la única restricción es que "el efecto de cualquier evaluación concurrente de las expresiones del operador y del operando está restringido a ser consistente con algún orden secuencial de evaluación". (R5RS sec. 4.1.3) [ 4 ]
( let (( ev ( lambda ( n ) ( display "Evaluando " ) ( display ( if ( procedure? n ) "procedimiento" n )) ( newline ) n ))) (( ev + ) ( ev 1 ) ( ev 2 ))) ===> 3Evaluación 1 Evaluación 2 Procedimiento de evaluación`ev` es un procedimiento que describe el argumento que se le pasa y luego devuelve el valor de dicho argumento. A diferencia de otros lenguajes Lisp, la aparición de una expresión en la posición del operador (el primer elemento) de una expresión Scheme es perfectamente válida, siempre que el resultado de la expresión en dicha posición sea un procedimiento.
Al llamar al procedimiento " + " para sumar 1 y 2, las expresiones (ev +), (ev 1) y (ev 2) pueden evaluarse en cualquier orden, siempre que el efecto no sea como si se evaluaran en paralelo. Por lo tanto, las siguientes tres líneas pueden mostrarse en cualquier orden mediante Scheme estándar cuando se ejecuta el código de ejemplo anterior, aunque el texto de una línea no puede intercalarse con el de otra, ya que eso violaría la restricción de evaluación secuencial.
macros higiénicas
En el estándar R5RS y en informes posteriores, la sintaxis de Scheme se puede extender fácilmente mediante el sistema de macros. El estándar R5RS introdujo un potente sistema de macros higiénicas que permite al programador añadir nuevas construcciones sintácticas al lenguaje utilizando un sublenguaje de coincidencia de patrones simple (R5RS sec 4.3). [ 4 ] Anteriormente, el sistema de macros higiénicas había sido relegado a un apéndice del estándar R4RS, como un sistema de "alto nivel" junto con un sistema de macros de "bajo nivel", ambos tratados como extensiones de Scheme en lugar de una parte esencial del lenguaje. [ 25 ]
Las implementaciones del sistema de macros higiénicas, también llamado syntax-rules, deben respetar el alcance léxico del resto del lenguaje. Esto se garantiza mediante reglas especiales de nomenclatura y alcance para la expansión de macros y evita errores de programación comunes que pueden ocurrir en los sistemas de macros de otros lenguajes de programación. R6RS especifica un sistema de transformación más sofisticado, , syntax-caseque ha estado disponible como extensión del lenguaje R5RS Scheme desde hace algún tiempo.
;; Define una macro para implementar una variante de "if" con una multiexpresión ;; rama verdadera y sin rama falsa. ( define-syntax when ( syntax-rules () (( when pred exp exps ... ) ( if pred ( begin exp exps ... )))))Las invocaciones de macros y procedimientos guardan un gran parecido —ambas son expresiones s—, pero se tratan de forma diferente. Cuando el compilador encuentra una expresión s en el programa, primero comprueba si el símbolo está definido como una palabra clave sintáctica dentro del ámbito léxico actual. Si es así, intenta expandir la macro, tratando los elementos de la cola de la expresión s como argumentos sin compilar código para evaluarlos, y este proceso se repite recursivamente hasta que no queden más invocaciones de macros. Si no es una palabra clave sintáctica, el compilador compila código para evaluar los argumentos de la cola de la expresión s y luego para evaluar la variable representada por el símbolo de la cabeza de la expresión s y llamarla como un procedimiento con las expresiones de la cola evaluadas como argumentos.
La mayoría de las implementaciones de Scheme también proporcionan sistemas de macros adicionales. Entre los más populares se encuentran los cierres sintácticos , las macros de renombrado explícito y define-macroun sistema de macros no higiénico similar al defmacrosistema proporcionado en Common Lisp .
La imposibilidad de especificar si una macro es higiénica o no es una de las deficiencias del sistema de macros. Los modelos alternativos de expansión, como los conjuntos de alcance, ofrecen una posible solución. [ 26 ]
Entornos y evaluación
Antes de R5RS, Scheme no tenía un equivalente estándar del evalprocedimiento que es omnipresente en otros Lisp, aunque el primer Lambda Paper lo había descrito evaluatecomo "similar a la función LISP EVAL" [ 18 ] y el primer Informe Revisado en 1978 lo reemplazó con enclose, que tomaba dos argumentos. El segundo, tercer y cuarto informe revisado omitieron cualquier equivalente de eval.
La razón de esta confusión es que en Scheme, con su ámbito léxico, el resultado de evaluar una expresión depende de dónde se evalúa. Por ejemplo, no está claro si el resultado de evaluar la siguiente expresión debería ser 5 o 6: [ 27 ]
( let (( nombre '+ )) ( let (( + * )) ( evaluar ( lista nombre 2 3 ))))Si se evalúa en el entorno externo, donde nameestá definido, el resultado es la suma de los operandos. Si se evalúa en el entorno interno, donde el símbolo "+" se ha vinculado al valor del procedimiento "*", el resultado es el producto de los dos operandos.
R5RS resuelve esta confusión especificando tres procedimientos que devuelven entornos y proporcionando un procedimiento evalque toma una expresión s y un entorno y evalúa la expresión en el entorno proporcionado. (R5RS sec. 6.5) [ 4 ] R6RS amplía esto proporcionando un procedimiento llamado environmentmediante el cual el programador puede especificar exactamente qué objetos importar al entorno de evaluación.
Con el esquema moderno (generalmente compatible con R5RS) para evaluar esta expresión, es necesario definir una función evaluateque puede tener este aspecto:
( definir ( evaluar expr ) ( eval expr ( interacción-entorno )))interaction-environmentes el entorno global del intérprete.
Tratamiento de valores no booleanos en expresiones booleanas
En la mayoría de los dialectos de Lisp, incluido Common Lisp, por convención el valor NILse evalúa como falso en una expresión booleana. En Scheme, desde el estándar IEEE de 1991, [ 3 ] todos los valores excepto #f, incluido NILel equivalente de en Scheme que se escribe como '(), se evalúan como verdadero en una expresión booleana. (R5RS sec. 6.3.1) [ 4 ]
Donde la constante que representa el valor booleano de verdadero es Ten la mayoría de los Lisp, en Scheme es #t.
Desunión de tipos de datos primitivos
En Scheme, los tipos de datos primitivos son disjuntos. Solo uno de los siguientes predicados puede ser verdadero para cualquier objeto Scheme: boolean?, pair?, symbol?, number?, char?, string?, vector?, port?, procedure?. (R5RS sec 3.2) [ 4 ]
En cambio, dentro del tipo de dato numérico, los valores numéricos se superponen. Por ejemplo, un valor entero satisface todos los predicados integer?, rational?, real?, complex?y number?al mismo tiempo. (R5RS sec 6.2) [ 4 ]
predicados de equivalencia
Scheme tiene tres tipos diferentes de equivalencia entre objetos arbitrarios denotados por tres predicados de equivalencia diferentes , operadores relacionales para probar la igualdad eq?, eqv?y equal?:
eq?se evalúa como verdadero a#fmenos que sus parámetros representen el mismo objeto de datos en la memoria;eqv?En general es lo mismo queeq?pero trata los objetos primitivos (por ejemplo, caracteres y números) de manera especial, de modo que los números que representan el mismo valor son igualeseqv?aunque no se refieran al mismo objeto;equal?compara estructuras de datos como listas, vectores y cadenas para determinar si tienen estructura yeqv?contenido congruentes. (R5RS sec. 6.1) [ 4 ]
En Scheme también existen operaciones de equivalencia dependientes del tipo: string=?y string-ci=?comparan dos cadenas (esta última realiza una comparación independiente de mayúsculas y minúsculas); char=?y char-ci=?comparan caracteres; =compara números. [ 4 ]
Comentarios
Hasta el estándar R5RS, el comentario estándar en Scheme era un punto y coma, lo que hace que el resto de la línea sea invisible para Scheme. Numerosas implementaciones han admitido convenciones alternativas que permiten que los comentarios se extiendan por más de una línea, y el estándar R6RS permite dos de ellas: una expresión s completa puede convertirse en un comentario (o "comentarse") precediéndola con #;(introducido en SRFI 62 [ 28 ] ) y se puede producir un comentario de varias líneas o "comentario de bloque" rodeando el texto con #|y |#.
Entrada/salida
La entrada y salida del esquema se basa en el tipo de datos del puerto . (R5RS sec 6.6) [ 4 ] R5RS define dos puertos predeterminados, accesibles con los procedimientos current-input-porty current-output-port, que corresponden a las nociones de Unix de entrada estándar y salida estándar . La mayoría de las implementaciones también proporcionan current-error-port. La redirección de entrada y salida estándar es compatible con el estándar, mediante procedimientos estándar como with-input-from-filey with-output-to-file. La mayoría de las implementaciones proporcionan puertos de cadena con capacidades de redirección similares, lo que permite realizar muchas operaciones normales de entrada-salida en búferes de cadena en lugar de archivos, utilizando procedimientos descritos en SRFI 6. [ 29 ] El estándar R6RS especifica procedimientos de puerto mucho más sofisticados y capaces y muchos tipos nuevos de puerto.
Los siguientes ejemplos están escritos en el esquema R5RS estricto.
Ejemplo 1: Con la salida predeterminada a (puerto de salida actual):
( let (( hello0 ( lambda () ( display "Hola mundo" ) ( newline )))) ( hello0 ))Ejemplo 2: Igual que el ejemplo 1, pero utilizando el argumento de puerto opcional para los procedimientos de salida.
( let (( hello1 ( lambda ( p ) ( display "Hola mundo" p ) ( newline p )))) ( hello1 ( current-output-port )))Ejemplo 3: Igual que el ejemplo 1, pero la salida se redirige a un archivo recién creado.
;; NB: with-output-to-file es un procedimiento opcional en R5RS ( let (( hello0 ( lambda () ( display "Hello world" ) ( newline )))) ( with-output-to-file "helloworldoutputfile" hello0 ))Ejemplo 4: Igual que el 2, pero con apertura explícita del archivo y cierre del puerto para enviar la salida a un archivo.
( let (( hello1 ( lambda ( p ) ( display "Hola mundo" p ) ( newline p ))) ( output-port ( open-output-file "helloworldoutputfile" ))) ( hello1 output-port ) ( close-output-port output-port ))Ejemplo 5: Igual que el 2, pero utilizando call-with-output-file para enviar la salida a un archivo.
( let (( hello1 ( lambda ( p ) ( display "Hola mundo" p ) ( newline p )))) ( call-with-output-file "helloworldoutputfile" hello1 ))Se proporcionan procedimientos similares para la entrada. El esquema R5RS proporciona los predicados input-port?y output-port?. Para la entrada y salida de caracteres, se proporcionan write-char, read-char, peek-chary . Para escribir y leer expresiones de Scheme, Scheme proporciona y . En una operación de lectura, el resultado devuelto es el objeto de fin de archivo si el puerto de entrada ha llegado al final del archivo, y esto se puede comprobar utilizando el predicado .char-ready?readwriteeof-object?
Con el estándar, SRFI 28 también define un procedimiento de formato básico similar a la función de Common Lisp format, de la cual recibe su nombre. [ 30 ]
Redefinición de los procedimientos estándar
En Scheme, los procedimientos están vinculados a variables. En R5RS, el estándar del lenguaje estableció formalmente que los programas pueden cambiar las vinculaciones de variables de los procedimientos integrados, redefiniéndolos efectivamente. (R5RS "Cambios en el lenguaje") [ 4 ] Por ejemplo, +se puede extender para aceptar cadenas además de números redefiniéndolo:
( set! + ( let (( original+ + )) ( lambda args ( apply ( if ( or ( null? args ) ( string? ( car args ))) string-append original+ ) args )))) ( + 1 2 3 ) ===> 6 ( + "1" "2" "3" ) ===> "123"En R6RS, cada enlace, incluidos los estándar, pertenece a alguna biblioteca, y todos los enlaces exportados son inmutables. (R6RS sec 7.1) [ 6 ] Debido a esto, la redefinición de procedimientos estándar mediante mutación está prohibida. En su lugar, es posible importar un procedimiento diferente con el nombre de uno estándar, lo que en efecto es similar a la redefinición.
Nomenclatura y convenciones de nombres
En Scheme estándar, los procedimientos que convierten de un tipo de dato a otro contienen la cadena de caracteres "->" en su nombre, los predicados terminan con un "?" y los procedimientos que modifican el valor de datos ya asignados terminan con un "!". Los programadores de Scheme suelen seguir estas convenciones.
En contextos formales como los estándares Scheme, se prefiere el término "procedimiento" a "función" para referirse a una expresión lambda o procedimiento primitivo. En el uso común, los términos "procedimiento" y "función" se utilizan indistintamente. La aplicación de un procedimiento a veces se denomina formalmente " combinación ".
Al igual que en otros lenguajes Lisp, el término " thunk " se utiliza en Scheme para referirse a un procedimiento sin argumentos. El término "recursión de cola propia" se refiere a la propiedad de todas las implementaciones de Scheme de que realizan una optimización de llamadas de cola para admitir un número indefinido de llamadas de cola activas .
La forma de los títulos de los documentos de estándares desde R3RS, "Revised n Report on the Algorithmic Language Scheme", es una referencia al título del documento estándar ALGOL 60 , "Revised Report on the Algorithmic Language Algol 60". La página de resumen de R3RS está modelada fielmente a partir de la página de resumen del Informe ALGOL 60. [ 31 ] [ 32 ]
Revisión de formularios y procedimientos estándar
El lenguaje se define formalmente en los estándares R5RS (1998) [ 4 ] , R6RS (2007) [ 6 ] y R7RS (2013) [ 5 ] . Estos describen "formas" estándar: palabras clave y sintaxis que las acompaña, las cuales proporcionan la estructura de control del lenguaje, y procedimientos estándar que realizan tareas comunes.
Formularios estándar
Esta tabla describe las formas estándar en Scheme. Algunas formas aparecen en más de una fila porque no se pueden clasificar fácilmente en una sola función del lenguaje.
Las formas marcadas con una "L" en esta tabla se clasifican como formas derivadas de "biblioteca" en el estándar y, en la práctica, a menudo se implementan como macros utilizando formas más fundamentales, lo que facilita mucho la tarea de implementación en comparación con otros lenguajes.
Si bien beginen R5RS se define como una sintaxis de biblioteca, el expansor debe conocerla para lograr la función de empalme. En R6RS ya no es una sintaxis de biblioteca.
Procedimientos estándar
Las dos tablas siguientes describen los procedimientos estándar del esquema R5RS. El esquema R6RS es mucho más extenso y un resumen de este tipo no sería práctico.
Algunos procedimientos aparecen en más de una fila porque no se pueden clasificar fácilmente en una sola función del lenguaje.
Los procedimientos de cadena y carácter que contienen "-ci" en sus nombres realizan comparaciones independientes de mayúsculas y minúsculas entre sus argumentos: las versiones en mayúscula y minúscula del mismo carácter se consideran iguales.
Las implementaciones de - y / que aceptan más de dos argumentos están definidas, pero se dejan como opcionales en R5RS.
Solicitudes de implementación del plan
Debido al minimalismo de Scheme, muchos procedimientos y formas sintácticas comunes no están definidos en el estándar. Para mantener el lenguaje principal pequeño y, al mismo tiempo, facilitar la estandarización de las extensiones, la comunidad de Scheme cuenta con un proceso de "Solicitud de Implementación de Scheme" (SRFI, por sus siglas en inglés) mediante el cual se definen las bibliotecas de extensión a través de un análisis detallado de las propuestas de extensión. Esto fomenta la portabilidad del código. Muchas de las SRFI son compatibles con todas o la mayoría de las implementaciones de Scheme.
Las SRFI con un soporte bastante amplio en diferentes implementaciones incluyen: [ 33 ]
- 0: construcción de expansión condicional basada en características
- 1: lista de bibliotecas
- 4: Tipos de datos vectoriales numéricos homogéneos
- 6: puertos de cadena básicos
- 8: recibir, vincular a múltiples valores
- 9: definición de tipos de registro
- 13: biblioteca de cadenas
- 14: biblioteca de conjuntos de caracteres
- 16: sintaxis para procedimientos de aridad variable
- 17: ¡conjunto generalizado!
- 18: Compatibilidad con multihilo
- 19: Tipos de datos de tiempo y procedimientos
- 25: primitivas de matrices multidimensionales
- 26: notación para especializar parámetros sin currificación
- 27: fuentes de bits aleatorios
- 28: cadenas de formato básico
- 29: localización
- 30: comentarios multilínea anidados
- 31: una forma especial para la evaluación recursiva
- 37: args-fold: un procesador de argumentos de programa
- 39: objetos de parámetros
- 41: transmisiones
- 42: comprensiones ávidas
- 43: biblioteca de vectores
- 45: primitivas para expresar algoritmos iterativos perezosos
- 60: enteros como bits
- 61: una cláusula condicional más general
- 66: vectores de octeto
- 67: comparar procedimientos
Implementaciones
El diseño elegante y minimalista ha convertido a Scheme en un objetivo popular para diseñadores de lenguajes, aficionados y educadores, y debido a su pequeño tamaño, el de un intérprete típico , también es una opción popular para sistemas embebidos y scripting . Esto ha dado como resultado decenas de implementaciones, [ 34 ] la mayoría de las cuales difieren tanto entre sí que portar programas de una implementación a otra es bastante difícil, y el pequeño tamaño del lenguaje estándar significa que escribir un programa útil de gran complejidad en Scheme estándar y portable es casi imposible. [ 14 ] El estándar R6RS especifica un lenguaje mucho más amplio, en un intento de ampliar su atractivo para los programadores.
Casi todas las implementaciones proporcionan un bucle tradicional de lectura-evaluación-impresión al estilo Lisp para el desarrollo y la depuración. Muchas también compilan programas Scheme a binario ejecutable. El soporte para incrustar código Scheme en programas escritos en otros lenguajes también es común, ya que la relativa simplicidad de las implementaciones de Scheme lo convierte en una opción popular para agregar capacidades de scripting a sistemas más grandes desarrollados en lenguajes como C. Los intérpretes de Scheme Gambit , Chicken y Bigloo compilan Scheme a C, lo que hace que la incrustación sea mucho más fácil. Además, el compilador de Bigloo se puede configurar para generar bytecode para la máquina virtual Java (JVM) y tiene un generador de bytecode experimental para .NET .
Algunas implementaciones admiten funciones adicionales. Por ejemplo, Kawa y JScheme ofrecen integración con clases Java , y los compiladores de Scheme a C suelen facilitar el uso de bibliotecas externas escritas en C, llegando incluso a permitir la inserción de código C en el código fuente de Scheme. Otro ejemplo es Pvts, que ofrece un conjunto de herramientas visuales que facilitan el aprendizaje de Scheme.
Uso
Scheme es ampliamente utilizado por varias [ 35 ] escuelas; en particular, varios cursos introductorios de ciencias de la computación utilizan Scheme junto con el libro de texto Structure and Interpretation of Computer Programs (SICP). [ 36 ] Durante los últimos 12 años, PLT ha dirigido el proyecto ProgramByDesign (anteriormente TeachScheme!), que ha expuesto a cerca de 600 profesores de secundaria y miles de estudiantes de secundaria a la programación rudimentaria en Scheme. La antigua clase introductoria de programación 6.001 del MIT se impartía en Scheme, [ 37 ] Aunque 6.001 ha sido reemplazada por cursos más modernos, SICP continúa impartiéndose en el MIT. [ 38 ] Del mismo modo, la clase introductoria en UC Berkeley , CS 61A, se impartió hasta 2011 completamente en Scheme, salvo pequeñas digresiones en Logo para demostrar el alcance dinámico. Hoy, al igual que el MIT, Berkeley ha reemplazado el programa de estudios con una versión más moderna que se enseña principalmente en Python 3 , pero el programa actual todavía se basa en el antiguo plan de estudios, y partes de la clase todavía se enseñan en Scheme. [ 39 ]
El libro de texto Cómo diseñar programas es utilizado por algunos institutos de educación superior para sus cursos introductorios de ciencias de la computación. El Instituto Politécnico de Worcester utiliza Scheme exclusivamente para su curso introductorio Introducción al diseño de programas (CS1101). [ 40 ] El Instituto Tecnológico Rose-Hulman utiliza Scheme en su curso más avanzado Conceptos de lenguajes de programación. [ 41 ] El curso básico de la Universidad de Brandeis , Estructura e interpretaciones de programas informáticos (COSI121b), también es impartido exclusivamente en Scheme por el científico informático teórico Harry Mairson . [ 42 ] La clase introductoria de la Universidad de Indiana , C211, se imparte completamente en Scheme. Una versión autodirigida del curso, CS 61AS, continúa utilizando Scheme. [ 43 ] Los cursos introductorios de ciencias de la computación en Yale y Grinnell College también se imparten en Scheme. [ 44 ] El antiguo curso introductorio de ciencias de la computación en la Universidad de Minnesota - Twin Cities, CSCI 1901, también utilizaba Scheme como su lenguaje principal, seguido de un curso que introducía a los estudiantes al lenguaje Java; [ 45 ] sin embargo, siguiendo el ejemplo del MIT, el departamento reemplazó 1901 con el CSCI 1133 basado en Python, [ 46 ] mientras que la programación funcional se cubre en detalle en el curso del tercer semestre CSCI 2041. [ 47 ]
El esquema también se utiliza/utilizaba para lo siguiente:
- El lenguaje de especificación y semántica de estilo de documentos (DSSSL), que proporciona un método para especificar hojas de estilo SGML , utiliza un subconjunto de Scheme. [ 48 ]
- El conocido editor de gráficos rasterizados de código abierto GIMP utiliza TinyScheme como lenguaje de scripting . [ 49 ]
- Guile ha sido adoptado por el proyecto GNU como su lenguaje de scripting oficial, y esa implementación de Scheme está integrada en aplicaciones como GNU LilyPond y GnuCash como lenguaje de scripting para extensiones. Asimismo, Guile solía ser el lenguaje de scripting del entorno de escritorio GNOME , [ 50 ] y GNOME aún cuenta con un proyecto que proporciona enlaces de Guile a su pila de bibliotecas. [ 51 ] Existe un proyecto para incorporar Guile a GNU Emacs , el programa insignia de GNU, reemplazando al intérprete Emacs Lisp actual . [ 52 ]
- Elk Scheme es utilizado por Synopsys como lenguaje de scripting para sus herramientas de diseño asistido por ordenador (CAD) tecnológico (TCAD) . [ 53 ]
- Shiro Kawai, programador sénior de la película Final Fantasy: The Spirits Within , utilizó Scheme como lenguaje de scripting para gestionar el motor de renderizado en tiempo real. [ 54 ]
- Google App Inventor para Android utiliza Scheme, donde Kawa se utiliza para compilar el código Scheme a bytecodes para la máquina virtual Java que se ejecuta en dispositivos Android. [ 55 ]
Véase también
- Fundamentos de los lenguajes de programación , libro de texto que utiliza Scheme como base.
Referencias
- ↑ "Influencias - The Rust Reference" . The Rust Reference . Consultado el 18 de abril de 2023 .
- ↑ Common LISP: El lenguaje, 2.ª ed., Guy L. Steele Jr. Digital Press; 1981. ISBN 978-1-55558-041-4"Common Lisp es un nuevo dialecto de Lisp, sucesor de MacLisp, fuertemente influenciado por ZetaLisp y, en cierta medida, por Scheme e InterLisp."
- 1 2 1178-1990 (Reafirmación 2008) Norma IEEE para el lenguaje de programación Scheme. Número de parte IEEE STDPD14209, reafirmada por unanimidad en una reunión del Comité de Revisión de Normas (RevCom) de la Junta de Normas IEEE-SA, el 26 de marzo de 2008 (punto 6.3 de las actas), actas de reafirmación consultadas en octubre de 2009. Este documento está disponible para su compra únicamente a través de IEEE y no se encuentra disponible en línea al momento de redactar este documento: 2009.
- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Richard Kelsey; William Clinger; Jonathan Rees; et al. (agosto de 1998). " Informe revisado 5 sobre el esquema del lenguaje algorítmico" . Higher-Order and Symbolic Computation . 11 (1): 7– 105. doi : 10.1023/A:1010051815785 . S2CID 14069423. Recuperado el 9 de agosto de 2012 .
- 1 2 3 "R7RS final disponible" (PDF) . 2013-07-06.
- 1 2 3 4 5 Sperber, Michael; Dybvig, R. Kent; Flatt, Matthew; Van Straaten, Anton; et al. (agosto de 2007). "Informe revisado 6 sobre el esquema de lenguaje algorítmico (R6RS)" . Comité directivo del esquema . Recuperado el 13 de septiembre de 2011 .
- 1 2 3 4 Sussman, Gerald Jay; Steele, Guy L. (1 de diciembre de 1998). "El primer informe sobre Scheme revisado". Higher-Order and Symbolic Computation . 11 (4): 399– 404. doi : 10.1023/A:1010079421970 . S2CID 7704398 .
- ↑ "Implementaciones de R6RS" . r6rs.org . Consultado el 24 de noviembre de 2017 .
- ↑ Abdulaziz Ghuloum (27-10-2007). "Bibliotecas R6RS y sistema de casos sintácticos (psyntax)" . Esquema Ikarus . Recuperado el 20-10-2009 .
- ↑ Keep, Andrew W.; Dybvig, R. Kent (noviembre de 2014). "Una representación en tiempo de ejecución de los tipos de registros de Scheme" . Journal of Functional Programming . 24 (6): 675–716 . doi : 10.1017/S0956796814000203 . S2CID 40001845 .
- ↑ "Informe revisado^6 sobre el esquema de lenguaje algorítmico, Apéndice E: cambios en el lenguaje" . Comité Directivo del Esquema. 26 de septiembre de 2007. Consultado el 20 de octubre de 2009 .
- ↑ "Electorado R6RS" . Comité Directivo del Plan. 2007. Consultado el 9 de agosto de 2012 .
- ↑ Marc Feeley (compilación) (26 de octubre de 2007). "Intenciones de los implementadores respecto a R6RS" . Comité Directivo del Esquema, lista de correo r6rs-discuss. Archivado del original el 20 de agosto de 2008. Consultado el 9 de agosto de 2012 .
- 1 2 Will Clinger, Marc Feeley, Chris Hanson, Jonathan Rees y Olin Shivers (2009-08-20). "Declaración de posición (borrador) " . Comité Directivo del Plan . Recuperado el 2012-08-09 .
{{cite web}}: CS1 maint: varios nombres: lista de autores ( enlace ) - ↑ "R7RS 9.º borrador disponible" (PDF) . 15/04/2013.
- ↑ Will Clinger (10 de mayo de 2013). "Extensión del período de votación" . Comité Directivo del Idioma del Esquema, lista de correo scheme-reports. Archivado del original el 21 de julio de 2013. Recuperado el 7 de julio de 2013 .
- ↑ La implementación de Scheme 48 se llama así porque el intérprete fue escrito por Richard Kelsey y Jonathan Rees en 48 horas (6 y 7 de agosto de 1986). Véase Richard Kelsey; Jonathan Rees; Mike Sperber (10 de enero de 2008). "Manual de referencia incompleto de Scheme 48 para la versión 1.8" . Jonathan Rees, s48.org . Consultado el 9 de agosto de 2012 .
- 1 2 Gerald Jay Sussman y Guy Lewis Steele Jr. (diciembre de 1975). "Scheme: un intérprete para el cálculo lambda extendido" (PDF) . AI Memos . AIM-349. MIT AI Lab . hdl : 1721.1/5794 . Consultado el 23 de diciembre de 2021 .
- ↑ Joel Moses (junio de 1970), La función de FUNCTION en LISP, o por qué el problema FUNARG debería llamarse el problema del entorno , hdl : 1721.1/5854 , AI Memo 199,
Una metáfora útil para la diferencia entre FUNCTION y QUOTE en LISP es pensar en QUOTE como una cubierta porosa o abierta de la función ya que las variables libres escapan al entorno actual. FUNCTION actúa como una cubierta cerrada o no porosa (de ahí el término "cierre" utilizado por Landin). Así, hablamos de expresiones Lambda "abiertas" (las funciones en LISP suelen ser expresiones Lambda) y expresiones Lambda "cerradas". [...] Mi interés en el problema del entorno comenzó cuando Landin, que tenía un profundo conocimiento del problema, visitó el MIT durante 1966-67. Entonces me di cuenta de la correspondencia entre las listas FUNARG, que son el resultado de la evaluación de expresiones Lambda "cerradas" en
LISP
, y
los cierres Lambda de
ISWIM .
- ↑ van Tonder, André (1 de enero de 2004). "Un cálculo lambda para la computación cuántica". SIAM Journal on Computing . 33 (5): 1109– 1135. arXiv : quant-ph/0307150 . doi : 10.1137/S0097539703432165 . S2CID 613571 .
- ↑ Niehren, J.; Schwinghammer, J.; Smolka, G. (noviembre de 2006). "Un cálculo lambda concurrente con futuros" (PDF) . Theoretical Computer Science . 364 (3): 338– 356. doi : 10.1016/j.tcs.2006.08.016 .
- ↑ Gerald Jay Sussman y Guy Lewis Steele Jr. (marzo de 1976). "Lambda: El imperativo definitivo" (postscript o PDF) . AI Memos . AIM-353. MIT AI Lab . hdl : 1721.1/5790 ."Lambda: El imperativo definitivo (transcripción)" . scheme.org .
- ↑ Gabriel, Richard P. ; Pitman, Kent (1988). "Problemas técnicos de separación en celdas de función y celdas de valor" . LISP y computación simbólica . Vol. 1, n.º 1 (publicado en junio de 1988). págs. 81–101 . doi : 10.1007/BF01806178 . Consultado el 9 de agosto de 2012 .
- 1 2 Philip L. Bewig (24-01-2008). "SRFI 41: Streams" . Los editores de SRFI, schemers.org . Recuperado el 09-08-2012 .
- ↑ William Clinger y Jonathan Rees, eds. (1991). "Revised 4 Report on the Algorithmic Language Scheme" . ACM Lisp Pointers . 4 (3): 1– 55. Recuperado el 9 de agosto de 2012 .
- ↑ Flatt, Matthew (2016). «Binding as sets of scopes». Actas del 43.º Simposio Anual ACM SIGPLAN-SIGACT sobre Principios de Lenguajes de Programación . págs. 705–717 . doi : 10.1145/2837614.2837620 . ISBN 978-1-4503-3549-2. S2CID 15401805 .
- ↑ Jonathan Rees, El esquema de las cosas La reunión de junio de 1992 Archivado el 16 de julio de 2011 en Wayback Machine (postscript), en Lisp Pointers, V(4), octubre-diciembre de 1992. Recuperado el 9 de agosto de 2012
- ↑ Taylor Campbell (21 de julio de 2005). "SRFI 62: Comentarios sobre expresiones S" . Los editores de SRFI, schemers.org . Consultado el 9 de agosto de 2012 .
- ↑ William D Clinger (1999-07-01). "SRFI 6: Puertos de cadena básicos" . Los editores de SRFI, schemers.org . Consultado el 2012-08-09 .
- ↑ Scott G. Miller (25 de junio de 2002). "SRFI 28: Cadenas de formato básico" . Los editores de SRFI, schemers.org . Consultado el 9 de agosto de 2012 .
- ↑ JW Backus; FL Bauer; J. Green; C. Katz; J. McCarthy; P. Naur; et al. (enero-abril de 1960). "Informe revisado sobre el lenguaje algorítmico Algol 60" . Numerische Mathematik, Communications of the ACM y Journal of the British Computer Society . Consultado el 9 de agosto de 2012 .
- ↑ Jonathan Rees; William Clinger, eds. (diciembre de 1986). "Revised(3) Report on the Algorithmic Language Scheme (Dedicated to the Memory of ALGOL 60)" . ACM SIGPLAN Notices . 21 (12): 37–79 . CiteSeerX 10.1.1.29.3015 . doi : 10.1145/15042.15043 . hdl : 1721.1/6424 . S2CID 43884422. Recuperado el 9 de agosto de 2012 .
- ↑ "Sistemas de esquemas que dan soporte a los SRFI" . Los editores de SRFI, schemers.org. 30 de agosto de 2009. Archivado del original el 20 de junio de 2021. Consultado el 9 de agosto de 2012 .
- ↑ 75 implementaciones conocidas de Scheme se enumeran en "scheme-faq-standards" . Wiki de la comunidad Scheme. 25-06-2009 . Consultado el 20-10-2009 .
- ↑ Ed Martin (2009-07-20). "Lista de escuelas que utilizan Scheme" . Schemers Inc. Archivado del original el 30-03-2009 . Recuperado el 20-10-2009 .
- ↑ "Lista de escuelas que utilizan SICP" . MIT Press. 26 de enero de 1999. Archivado del original el 15 de junio de 2008. Consultado el 20 de octubre de 2009 .
- ↑ Eric Grimson (Primavera de 2005). "6.001 Estructura e interpretación de programas informáticos" . MIT Open Courseware . Consultado el 20 de octubre de 2009 .
- ↑ Alex Vandiver; Nelson Elhage; et al. (enero de 2009). "6.184 - Los zombis beben 6.001 con cafeína" . MIT CSAIL. Archivado del original el 28 de agosto de 2009. Consultado el 20 de octubre de 2009 .
- ↑ John DeNero (otoño de 2019). "Ciencias de la Computación 61A, Berkeley" . Departamento de Ingeniería Eléctrica y Ciencias de la Computación, Berkeley. Archivado del original el 11 de noviembre de 2020. Consultado el 17 de diciembre de 2019 .
- ↑ CS 1101: Introducción al diseño de programas (A05): software del curso , Instituto Politécnico de Worcester
- ↑ "CSSE 304: Conceptos de lenguajes de programación" . Instituto Tecnológico Rose-Hulman .
- ↑ "Programa de estudios CS121b Primavera 2021" (PDF) . Universidad de Brandeis .
- ↑ "Inicio" . berkeley-cs61as.github.io .
- ↑ Dana Angluin (otoño de 2009). "Introducción a la informática (CPSC 201)" . The Zoo, Departamento de Informática de la Universidad de Yale . Consultado el 20 de octubre de 2009 .
- ↑ Estructura de la programación de computadoras I Archivado el 19 de junio de 2010 en Wayback Machine , Departamento de Ciencias de la Computación, Universidad de Minnesota, primavera de 2010 (consultado el 30 de enero de 2010).
- ↑ Descripciones de cursos obligatorios de CSci y otra información archivada el 25/10/2019 en Wayback Machine , Departamento de Ciencias de la Computación, Universidad de Minnesota (consultado el 25/10/2019)
- ↑ CSCI 2041—Nuevo curso. Comité Curricular de Ingeniería Informática, Universidad de Minnesota (consultado el 25/10/2019)
- ↑ Robin Cover (25/02/2002). "DSSSL - Lenguaje de especificación y semántica de estilo de documento. ISO/IEC 10179:1996" . Portada . Consultado el 09/08/2012 .
- ↑ " El principal lenguaje de scripting para GIMP que se ha incorporado a él hoy en día es Scheme. " De Dov Grobgeld (2002). "The GIMP Basic Scheme Tutorial" . El equipo de GIMP . Consultado el 9 de agosto de 2012 .
- ↑ Todd Graham Lewis; David Zoll; Julian Missig (2002). "Preguntas frecuentes de GNOME del Archivo de Internet" . El equipo de GNOME, gnome.org. Archivado del original el 22 de mayo de 2000. Consultado el 9 de agosto de 2012 .
- ↑ "guile-gnome" . Free Software Foundation . Consultado el 9 de agosto de 2012 .
- ↑ "Astucia en Emacs" . EmacsConf . Consultado el 5 de diciembre de 2025 .
- ↑ Laurence Brevard (09/11/2006). " Actualización del programa Synopsys MAP-in SM : Foro de desarrolladores de interoperabilidad EDA" (PDF) . Synopsis Inc. Recuperado el 09/08/2012 .
- ↑ Kawai, Shiro (octubre de 2002). "Uniendo cosas: Scheme en la producción de contenido CG en tiempo real" . Actas de la Primera Conferencia Internacional Lisp, San Francisco : 342–348 . Recuperado el 9 de agosto de 2012 .
- ↑ Bill Magnuson; Hal Abelson y Mark Friedman (11 de agosto de 2009). "Bajo el capó de App Inventor para Android" . Google Inc., blog oficial de Google Research . Consultado el 9 de agosto de 2012 .
Lecturas adicionales
- Introducción a Scheme y su implementación ( un espejo )
- Christopher T. Haynes (22 de junio de 1999). "La experiencia de estandarización del lenguaje de programación Scheme" .
- Guy L. Steele Jr. , Richard P. Gabriel . "La evolución de Lisp" (PDF) . Archivado del original (PDF) el 11 de junio de 2016.
- Gerald Jay Sussman y Guy Lewis Steele Jr. (diciembre de 1975). . Vol. AI Memo 349. Laboratorio de Inteligencia Artificial del MIT . CiteSeerX 10.1.1.128.80 – vía Wikisource .
Enlaces externos
- scheme.org proporciona enlaces a muchos recursos de Scheme, incluidas las especificaciones.
Programación en Scheme en Wikibooks- Introducción al programa
Escribe tu propio plan en 48 horas en Wikibooks
Contenido multimedia relacionado con Scheme (lenguaje de programación) en Wikimedia Commons.- Esquema semanal
- Bookmarklet que añade un REPL interactivo de Scheme a cualquier sitio web.
- Scheme (lenguaje de programación)
- Lenguajes de programación académica
- Lenguajes de programación de tipado dinámico
- Lenguajes de programación con sintaxis extensible
- Familia de lenguajes de programación Lisp
- Lenguajes de programación multiparadigma
- Lenguajes de programación creados en 1975
