stringtranslate.com

Esquema (lenguaje de programación)

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 AI Lab) y publicado por sus desarrolladores, Guy L. Steele y Gerald Jay Sussman , a través de una serie de memorandos ahora conocidos como Lambda Papers . Fue el primer dialecto de Lisp en elegir el alcance léxico y el primero en requerir implementaciones para realizar la optimización de llamadas de cola , brindando 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 que admitió 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 n revisado sobre el esquema de lenguaje algorítmico (R n RS). Un estándar ampliamente implementado es R5RS (1998). [4] La norma del Esquema ratificada más recientemente es "R7RS-small" (2013). [5] El R6RS, más expansivo y modular, fue ratificado en 2007. [6] Ambos descienden del R5RS; El cronograma a continuación refleja el orden cronológico de ratificación.

Historia

Orígenes

Scheme comenzó en la década de 1970 como un intento de comprender el modelo Actor de Carl Hewitt , para cuyo propósito 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", en la tradición de otros lenguajes derivados de Lisp como Planner o Conniver . El nombre actual surgió del uso por parte de los autores del sistema operativo ITS , que limitaba los nombres de archivos a dos componentes de como máximo seis caracteres cada uno. Actualmente, "Schemer" se usa comúnmente para referirse a un programador de Scheme.

R6RS

Un nuevo proceso de estandarización del lenguaje comenzó en el taller Scheme de 2003, con el objetivo de producir un estándar R6RS en 2006. Este proceso rompió con el enfoque anterior de unanimidad R n RS.

R6RS presenta un sistema de módulos estándar, lo que permite una divisió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 de la nueva norma, anunciada el 28 de agosto de 2007. [6]

Actualmente, las versiones más recientes de varias implementaciones de Scheme [8] admiten el estándar R6RS. Existe una implementación de referencia portátil de las bibliotecas implícitamente escalonadas propuestas para R6RS, llamada psyntax, que se carga y arranca correctamente en varias implementaciones de Scheme más antiguas. [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 el diseño de la memoria. También calculó la máscara de bits del campo de objeto y las máscaras de bits de campo de objeto de esquema mutables, y ayudó al recolector de basura a saber qué hacer con los campos sin recorrer toda la lista de campos que están guardados en el RTD. RTD permite a los usuarios ampliar el RTD básico para crear un nuevo sistema de registro. [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 ahora puede aparecer en los símbolos e identificadores de Scheme , y hay otros cambios menores en las reglas léxicas. Los datos de caracteres ahora también se especifican 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 y contienen procedimientos y formas sintácticas que anteriormente 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. Las reglas de sintaxis han sido reemplazadas por una función de abstracción sintáctica más expresiva (syntax-case) que permite el uso de todo Scheme en el momento de la expansión macro. Ahora se requieren implementaciones compatibles para soportar la torre numérica completa de Scheme , y la semántica de los números se ha ampliado, principalmente en la dirección del soporte para el estándar IEEE 754 para 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 dividir Scheme en dos lenguajes: un gran lenguaje de programación moderno para programadores; y una versión pequeña, un subconjunto de la versión grande que conserva el minimalismo elogiado por educadores e implementadores ocasionales. [14] Se crearon dos grupos de trabajo para trabajar en estas dos nuevas versiones de Scheme. El sitio del Proceso de Informes del Esquema tiene enlaces a los estatutos de los grupos de trabajo, debates públicos y sistema de seguimiento de problemas.

El noveno borrador de R7RS (lenguaje pequeño) estuvo disponible el 15 de abril de 2013. [15] Una votación que ratificó este borrador se cerró el 20 de mayo de 2013, [16] y el informe final ha estado disponible desde el 6 de agosto de 2013, describiendo "el lenguaje 'pequeño' 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 muy simple de Scheme se basa en expresiones-s , listas entre paréntesis en las que un operador de prefijo va seguido de sus argumentos. Por tanto, los programas de esquema constan de secuencias de listas anidadas. Las listas también son la estructura de datos principal en Scheme, lo que lleva 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 Lisp comparten la dependencia de las listas como estructuras de datos. Scheme hereda un rico conjunto de primitivas de procesamiento de listas como y de conssus progenitores Lisp. Scheme utiliza variables escritas de forma estricta pero dinámica y admite procedimientos de primera clase . Por tanto, los procedimientos pueden asignarse como valores a variables o pasarse como argumentos a procedimientos.carcdr

Esta sección se concentra principalmente en las características innovadoras del lenguaje, incluidas aquellas características que distinguen a Scheme de otros Lisps. A menos que se indique lo contrario, las descripciones de las funciones se refieren al estándar R5RS. En los ejemplos proporcionados en esta sección, la notación "===> resultado" se utiliza para indicar el resultado de evaluar la expresión en la línea inmediatamente anterior. Esta es la misma convención utilizada 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 es atribuible 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 R5RS Scheme, 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 unión de variables es la expresión lambda, porque todas las demás construcciones de unión de variables se pueden explicar en términos de expresiones lambda". [4]

Formas fundamentales : define, lambda, quote, if, define-syntax, let-syntax, letrec-syntax, syntax-rules, set!
Formas derivadas : hacer, dejar, dejar*, letrec, cond, caso, y, o, comenzar, nombrado dejar, retrasar, sin comillas, sin comillas, cuasi comillas

Ejemplo: una macro para implementar letcomo una expresión que se utiliza lambdapara realizar las vinculaciones de variables.

( definir-sintaxis let ( reglas-sintaxis () (( let (( var expr ) ... ) cuerpo ... ) (( lambda ( var ... ) cuerpo ... ) 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 instancias 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 deseado del proceso de diseño. "En realidad estábamos tratando de construir algo complicado y descubrimos, por casualidad, que habíamos diseñado accidentalmente algo que cumplía con 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 simple— podría servir como núcleo de un lenguaje de programación potente y expresivo". [7]

Alcance léxico

Como la mayoría de los lenguajes de programación modernos y a diferencia de Lisps anteriores como Maclisp , Scheme tiene un alcance léxico: todas las posibles vinculaciones de variables en una unidad de programa se pueden analizar leyendo el texto de la unidad de programa sin tener en cuenta los contextos en los que se puede llamar. Esto contrasta con el alcance dinámico que era característico de los primeros dialectos Lisp, debido a los costos de procesamiento asociados con los métodos primitivos de sustitución textual utilizados para implementar algoritmos de alcance léxico en los compiladores e intérpretes de la época. En esos Lisps, era perfectamente posible que una referencia a una variable libre dentro de un procedimiento hiciera referencia a enlaces bastante distintos externos al 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 Actor de Hewitt en Lisp. [7]

Las ideas clave sobre cómo introducir el alcance léxico en un dialecto Lisp se popularizaron en el artículo Lambda de 1975 de Sussman y Steele, "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 Memorándum de AI 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" por parte de 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. Pero los primeros Lisps no eran expresiones adecuadas del cálculo lambda debido a su tratamiento de variables libres . [7]

Un sistema lambda formal tiene axiomas y una regla de cálculo completa. Es útil para el análisis utilizando lógica y herramientas matemáticas. En este sistema, el cálculo puede verse como 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 de una poderosa lógica matemática. En segundo lugar, puede reducir la necesidad de que los programadores consideren los detalles de implementación, porque puede usarse para imitar la evaluación de la máquina. Finalmente, el cálculo lambda creó una metateoría sustancial. [21]

La introducción del alcance léxico resolvió el problema al hacer 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 podría usarse 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 Lisps, mediante el uso de expresiones lambda no como simples instancias de procedimientos sino como "control". modificadores de estructuras y entornos". [22] Introdujeron el estilo de paso de continuación junto con su primera descripción de Scheme en el primero de los documentos Lambda, y en artículos posteriores, procedieron a demostrar el poder bruto de este uso práctico del cálculo lambda.

Estructura de bloque

Scheme hereda su estructura de bloques de lenguajes estructurados en bloques anteriores, particularmente ALGOL . En Scheme, los bloques se implementan mediante tres construcciones vinculantes : y let. Por ejemplo, la siguiente construcción crea un bloque en el que un símbolo llamado está vinculado al número 10:let*letrecvar

( defina var "ganso" ) ;; Cualquier referencia a var aquí estará vinculada a "goose" ( let (( var 10 )) ;; las declaraciones van aquí. Cualquier referencia a var aquí estará vinculada a 10. ) ;; Cualquier referencia a var aquí estará vinculada a "ganso"      

Los bloques se pueden anidar para crear estructuras de bloques arbitrariamente complejas según las necesidades del programador. El uso de estructuración de bloques para crear enlaces locales alivia el riesgo de colisión de espacios de nombres que de otro modo podría ocurrir.

Una variante de let, let*permite que los enlaces hagan referencia a variables definidas anteriormente en la misma construcción, por lo tanto:

( let* (( var1 10 ) ( var2 ( + var1 12 ))) ;; Pero la definición de var1 no podría referirse a var2 )        

La otra variante, letrecestá diseñada para permitir que los procedimientos recursivos entre sí se vinculen entre sí.

;; Cálculo de las secuencias masculinas y femeninas de Hofstadter como lista de pares( definir ( hofstadter-hombre-mujer n ) ( letrec (( mujer ( lambda ( n ) ( if ( = n 0 ) 1 ( - n ( hombre ( mujer ( - n 1 ))))))) ( hombre ( lambda ( n ) ( if ( = n 0 ) 0 ( - n ( hembra ( masculino ( - n 1 )))))))) ( let loop (( i 0 )) ( if ( > in ) ' ( ) ( contras ( contras ( hembra i ) ( macho i )) ( bucle ( + 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 conocer las definiciones utilizadas en este ejemplo).

Todos los procedimientos enlazados en un solo letrecpueden hacer referencia entre sí por su nombre, así como también a valores de variables definidas anteriormente en el mismo letrec, pero no pueden hacer referencia a valores definidos más adelante en el mismo letrec.

Una variante de let, la forma "named let", 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 del formulario let. El cuerpo podrá repetirse según se desee llamando al procedimiento. El let nombrado se usa ampliamente para implementar la iteración.

Ejemplo: un contador simple

( let loop (( n 1 )) ( if ( > n 10 ) ' () ( contras n ( loop ( + n 1 )))))              ===> ( 1 2 3 4 5 6 7 8 9 10 )          

Como cualquier procedimiento en Scheme, el procedimiento creado en el let nombrado es un objeto de primera clase.

Recursividad de cola adecuada

Scheme tiene una construcción de iteración, dopero es más idiomático en Scheme usar recursividad de cola para expresar iteración . Se requieren implementaciones de Scheme que cumplan con los estándares para optimizar las llamadas de cola a fin de admitir un número ilimitado de llamadas de cola activas (R5RS sec. 3.5) [4] , una propiedad que el informe de Scheme describe como recursividad de cola adecuada , lo que hace que sea seguro para los programadores de Scheme Escriba algoritmos iterativos utilizando estructuras recursivas, que a veces son más intuitivas. Los procedimientos recursivos de cola y el formulario con nombrelet brindan soporte para la iteración utilizando la recursividad de cola.

;; Construyendo una lista de cuadrados del 0 al 9: ;; Nota: bucle es simplemente un símbolo arbitrario utilizado como etiqueta. Cualquier símbolo servirá.( definir ( lista de cuadrados n ) ( let loop (( i n ) ( res ' ())) ( if ( < i 0 ) res ( loop ( - i 1 ) ( contras ( * 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 retrocesos .

Las continuaciones se pueden utilizar para emular el comportamiento de las declaraciones 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 xque devuelve lstverdadero (func x).

( definir ( buscar-primera función lst ) ( llamada-con-continuación-actual ( lambda ( retorno-inmediatamente ) ( para cada ( lambda ( x ) ( if ( func x ) ( retorno-inmediatamente x ))) lst ) # f )))                (¿ encontrar el primer entero? ' ( 1/2 3/4 5.6 7 8/9 10 11 )) ===> 7 ( encontrar el primer cero? ' ( 1 2 3 4 )) ===> #f               

El siguiente ejemplo, un rompecabezas de programador tradicional, muestra que Scheme puede manejar continuaciones como objetos de primera clase, vinculándolas a variables y pasándolas como argumentos a procedimientos.

( let* (( yin (( lambda ( cc ) ( display "@" ) cc ) ( llamada-con-continuación-actual ( lambda ( c ) c )))) ( yang (( lambda ( cc ) ( display "* " ) cc ) ( llamada con continuación actual ( lambda ( c ) c ))))) ( yin yang ))                      

Cuando se ejecuta, este código muestra una secuencia de conteo:@*@**@***@****@*****@******@*******@********...

Espacio de nombres compartido para procedimientos y variables.

A diferencia de Common Lisp, todos los datos y procedimientos en Scheme comparten un espacio de nombres común, mientras que en Common Lisp las funciones y los datos tienen espacios de nombres separados , lo que hace posible que una función y una variable tengan el mismo nombre y requieren una notación especial para referirse a un funcionar como un valor. Esto a veces se conoce 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 utilizan para manipular y vincular datos se pueden utilizar para vincular procedimientos. No existe un equivalente de Common Lisp defuny #'primitivos.

;; Variable vinculada a un número: ( defina f 10 ) f ===> 10 ;; Mutación (alterando el valor ligado) ( set! f ( + f f 6 )) f ===> 26 ;; Asignando un procedimiento a la misma variable: ( set! f ( lambda ( n ) ( + n 12 ))) ( f 6 ) ===> 18 ;; Asignando el resultado de una expresión a la misma variable: ( set! f ( f 1 )) f ===> 13 ;; programación funcional: ( aplicar + ' ( 1 2 3 4 5 6 )) ===> 21 ( set! f ( lambda ( n ) ( + n 100 ))) ( mapa 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 han dado al Esquema un carácter particular, pero que no son el resultado directo del diseño original.

Torre numérica

Scheme especifica un conjunto comparativamente completo de tipos de datos numéricos que incluyen tipos complejos y racionales , lo que se conoce en Scheme como la torre numérica (R5RS sec. 6.2 [4] ). El estándar los trata como abstracciones y no compromete al implementador a ninguna representación interna particular.

Los números pueden tener la cualidad de exactitud. Un número exacto sólo puede producirse mediante una secuencia de operaciones exactas que impliquen otros números exactos; por tanto, la inexactitud es contagiosa. El estándar especifica que dos implementaciones cualesquiera deben 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 utilizar para cambiar la exactitud de un número. inexact->exactproduce "el número exacto que es numéricamente más cercano al argumento". exact->inexactproduce "el número inexacto que es numéricamente más cercano al 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, no se requiere que las implementaciones de Scheme implementen toda la torre numérica, pero deben implementar "un subconjunto coherente tanto con los propósitos de la implementación como con el espíritu del lenguaje Scheme" (R5RS sec. 6.2.3). [4] El nuevo estándar R6RS 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, e implementar ciertos procedimientos... para que siempre devuelvan resultados exactos cuando se les dan 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 ( defina x ( + 1/3 1/4 -1/5 -1/3i 405/50+2/3i )) x ===> 509/60+1/ 3i ;; Verifique la exactitud. (¿ exacto? x ) ===> #t          

Ejemplo 2: La misma aritmética en una implementación que no admite números racionales exactos ni números complejos, pero acepta números reales en notación racional.

;; Suma de cuatro números reales racionales ( defina xr ( + 1/3 1/4 -1/5 405/50 )) ;; Suma de dos números reales racionales ( definir xi ( + -1/3 2/3 )) xr ===> 8.48333333333333 xi ===> 0.333333333333333 ;; Verifique la exactitud. ( ¿exacto? xr ) ===> #f ( ¿exacto? xi ) ===> #f                

Ambas implementaciones cumplen con el estándar R5RS pero la segunda no cumple con R6RS porque no implementa la torre numérica completa.

Evaluación retrasada

El esquema apoya la evaluación retrasada a través del delayformulario y el procedimiento force.

( define un 10 ) ( define eval-aplus2 ( retraso ( + a 2 ))) ( set! a 20 ) ( fuerza eval-aplus2 ) ===> 22 ( define eval-aplus50 ( retraso ( + a 50 ))) ( let (( a 8 )) ( forzar eval-aplus50 )) ===> 70 ( set! a 100 ) ( forzar eval-aplus2 ) ===> 22                         

Se conserva el contexto léxico de la definición original de promesa, y su valor también se conserva después del primer uso de force. La promesa sólo se evalúa una vez.

Estas primitivas, que producen o manejan valores conocidos como promesas , se pueden utilizar para implementar construcciones de evaluación diferidas avanzadas , como secuencias . [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 procesador ) y usando la memorización para garantizar que solo se evalúe una vez, independientemente del número de veces forceque se llame (R5RS sec. 6.4 ). [4]

SRFI 41 permite la expresión de secuencias finitas e infinitas con extraordinaria economía. Por ejemplo, esta es una definición de la secuencia de Fibonacci usando las funciones definidas en SRFI 41: [24]

;; Defina la secuencia de Fibonacci: ( defina mentiras ( stream-cons 0 ( stream-cons 1 ( stream-map + fibs ( stream-cdr fibs ))))) ;; Calcule el centésimo número en la secuencia: ( stream-ref fibs 99 ) ===> 218922995834555169026             

Orden de evaluación de los argumentos del procedimiento.

La mayoría de Lisps especifican un orden de evaluación para los argumentos de los procedimientos. El esquema no. 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 llamada por llamada, y la única restricción es que "el efecto de cualquier evaluación concurrente del operador y Las expresiones de operandos están obligadas a ser coherentes con algún orden secuencial de evaluación". (R5RS sección 4.1.3) [4]

( let (( ev ( lambda ( n ) ( mostrar "Evaluando " ) ( mostrar ( if ( procedimiento? n ) "procedimiento" n )) ( nueva línea ) n ))) (( ev + ) ( ev 1 ) ( ev 2 ))) ===> 3                   
Evaluació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 del argumento. A diferencia de otros Lisps, la aparición de una expresión en la posición del operador (el primer elemento) de una expresión de Scheme es bastante legal, siempre que el resultado de la expresión en la posición del operador 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 y cuando el efecto no sea como si fueran evaluadas en paralelo. . Por lo tanto, las siguientes tres líneas pueden mostrarse en cualquier orden según el esquema estándar cuando se ejecuta el código de ejemplo anterior, aunque el texto de una línea no puede intercalarse con otra porque eso violaría la restricción de evaluación secuencial.

Macros higiénicas

En el estándar R5RS y también en informes posteriores, la sintaxis de Scheme se puede ampliar fácilmente a través del sistema de macros. El estándar R5RS introdujo un potente sistema macro higiénico que permite al programador agregar nuevas construcciones sintácticas al lenguaje utilizando un sublenguaje de coincidencia de patrones simple (R5RS sec 4.3). [4] Antes de esto, el macrosistema higiénico había sido relegado a un apéndice del estándar R4RS, como un sistema de "alto nivel" junto con un macrosistema de "bajo nivel", los cuales fueron tratados como extensiones de Scheme en lugar de un parte esencial de la lengua. [25]

Se requieren implementaciones del macrosistema higiénico, también llamado syntax-rules, para respetar el alcance léxico del resto del lenguaje. Esto está garantizado por 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 una extensión de lenguaje para R5RS Scheme durante algún tiempo.

;; Definir una macro para implementar una variante de "if" con una multiexpresión ;; rama verdadera y ninguna rama falsa. ( definir-sintaxis cuando ( reglas-sintaxis () (( cuando pred exp exps ... ) ( si pred ( comenzar exp exps ... )))))              

Las invocaciones de macros y procedimientos guardan un gran parecido (ambas son expresiones s), pero se tratan de manera diferente. Cuando el compilador encuentra una expresión s en el programa, primero verifica si el símbolo está definido como una palabra clave sintáctica dentro del alcance léxico actual. Si es así, intenta expandir la macro, tratando los elementos al final de la expresión s como argumentos sin compilar código para evaluarlos, y este proceso se repite de forma recursiva hasta que no queden invocaciones de macro. Si no es una palabra clave sintáctica, el compilador compila código para evaluar los argumentos al final de la expresión s y luego evaluar la variable representada por el símbolo al principio de la expresión s y llamarla como un procedimiento con la expresiones de cola evaluadas que se le pasan como argumentos.

La mayoría de las implementaciones de Scheme también proporcionan macrosistemas adicionales. Entre los más populares se encuentran los cierres sintácticos , el cambio de nombre explícito de macros y define-macroun sistema de macros no higiénico similar al defmacrosistema proporcionado en Common Lisp .

La incapacidad de especificar si una macro es higiénica o no es una de las deficiencias del sistema macro. Los modelos alternativos de expansión, como los conjuntos de alcance, proporcionan una solución potencial. [26]

Entornos y evaluación.

Antes de R5RS, Scheme no tenía un equivalente estándar del evalprocedimiento que es omnipresente en otros Lisps, aunque el primer documento Lambda 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 Tomó dos argumentos. Los informes revisados ​​segundo, tercero y cuarto omitieron cualquier equivalente de eval.

La razón de esta confusión es que en Scheme con su alcance 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 debe ser 5 o 6: [27]

( let (( nombre '+ )) ( let (( + * )) ( evaluar ( lista nombre 2 3 ))))          

Si se evalúa en el entorno exterior, donde nameestá definido, el resultado es la suma de los operandos. Si se evalúa en el entorno interno, donde el símbolo "+" ha sido 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 mediante environmentel cual el programador puede especificar exactamente qué objetos importar al entorno de evaluación.

Con un esquema moderno (generalmente compatible con R5RS) para evaluar esta expresión, es necesario definir una función evaluateque puede verse así:

( definir ( evaluar expr ) ( eval expr ( entorno de interacción )))     

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 en 1991, [3] todos los valores excepto #f, incluido NILel equivalente de Scheme que se escribe como '(), se evalúan como el valor verdadero en una expresión booleana. (R5RS sección 6.3.1) [4]

Mientras que la constante que representa el valor booleano de verdadero es Ten la mayoría de Lisps, en Scheme es #t.

Desarticulación de tipos de datos primitivos

En Scheme, los tipos de datos primitivos están separados. Sólo uno de los siguientes predicados puede ser verdadero para cualquier objeto Scheme: boolean?, pair?, symbol?, number?, char?, string?, vector?, port?, procedure?. (R5RS seg 3.2) [4]

En el tipo de datos numérico, por el contrario, los valores numéricos se superponen. Por ejemplo, un valor entero satisface todos los predicados integer?, rational?, real?y al mismo tiempo. (R5RS seg. 6.2) [4]complex?number?

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?:

Las operaciones de equivalencia dependientes del tipo también existen en Scheme: string=?y string-ci=?comparan dos cadenas (esta última realiza una comparación independiente de mayúsculas y minúsculas); char=?y char-ci=?comparar personajes; =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 a 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 |#.

De entrada y salida

La entrada y salida del esquema se basan 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 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 está respaldada por 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 que muchas operaciones normales de entrada y salida se realicen 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 nuevos tipos de puerto.

Los siguientes ejemplos están escritos en estricto esquema R5RS.

Ejemplo 1: con la salida predeterminada en (puerto-salida-actual):

( let (( hola0 ( lambda () ( mostrar "Hola mundo" ) ( nueva línea )))) ( hola0 ))      

Ejemplo 2: Como 1, pero usando el argumento de puerto opcional para generar procedimientos

( let (( hola1 ( lambda ( p ) ( mostrar "Hola mundo" p ) ( nueva línea p )))) ( hola1 ( puerto de salida actual )))          

Ejemplo 3: como 1, pero la salida se redirige a un archivo recién creado

;; NB: with-output-to-file es un procedimiento opcional en R5RS ( let (( hola0 ( lambda () ( mostrar "Hola mundo" ) ( nueva línea )))) ( with-output-to-file "helloworldoutputfile" hello0 ) )         

Ejemplo 4: Como 2, pero con el archivo abierto explícito y el puerto cerrado para enviar la salida al archivo

( let (( hola1 ( lambda ( p ) ( mostrar "Hola mundo" p ) ( nueva línea p ))) ( puerto de salida ( abrir archivo de salida "helloworldoutputfile " ))) ( puerto de salida hola1 ) ( cerrar salida -puerto puerto-salida ))               

Ejemplo 5: Como 2, pero usando call-with-output-file para enviar resultados a un archivo.

( let (( hola1 ( lambda ( p ) ( mostrar "Hola mundo" p ) ( nueva línea p )))) ( llamada-con-archivo-de-salida "helloworldoutputfile" hola1 ))           

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, y . 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 probar usando el predicado .read-charpeek-charchar-ready?readwriteeof-object?

Con el estándar, SRFI 28 también define un procedimiento de formateo básico que se asemeja a la función de Common Lisp format, del cual recibe su nombre. [30]

Redefinición de procedimientos estándar

En Scheme, los procedimientos están vinculados a variables. En R5RS, el estándar del lenguaje exigía formalmente que los programas pudieran cambiar los enlaces variables de los procedimientos integrados, redefiniéndolos efectivamente. (R5RS "Cambios de idioma") [4] Por ejemplo, +se puede ampliar para aceptar cadenas y 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, todos los enlaces, incluidos los estándar, pertenecen 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 por mutación está prohibida. En cambio, es posible importar un procedimiento diferente bajo el nombre de estándar, lo que en realidad es similar a una redefinición.

Nomenclatura y convenciones de nomenclatura

En el esquema estándar, los procedimientos que convierten de un tipo de datos a otro contienen la cadena de caracteres "->" en su nombre, los predicados terminan con "?" y los procedimientos que cambian el valor de datos ya asignados terminan con "!". Los programadores de Scheme suelen seguir estas convenciones.

En contextos formales como los estándares Scheme, la palabra "procedimiento" se utiliza preferentemente a "función" para referirse a una expresión lambda o un procedimiento primitivo. En el uso normal, las palabras "procedimiento" y "función" se utilizan indistintamente. La aplicación del procedimiento a veces se denomina formalmente combinación .

Como en otros Lisps, el término " thunk " se utiliza en Scheme para referirse a un procedimiento sin argumentos. El término "recursividad de cola adecuada" 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 estándar desde R3RS, " Informe n revisado sobre el esquema de lenguaje algorítmico", es una referencia al título del documento estándar ALGOL 60 , "Informe revisado sobre el lenguaje algorítmico Algol 60", la página de resumen de R3RS está estrechamente modelado en la página Resumen del Informe ALGOL 60. [31] [32]

Revisión de formularios y procedimientos estándar.

El lenguaje está definido formalmente en los estándares R5RS (1998) [4] y R6RS (2007). [6] Describen "formas" estándar: palabras clave y la sintaxis que las acompaña, que proporcionan la estructura de control del lenguaje, y procedimientos estándar que realizan tareas comunes.

Formularios estándar

Esta tabla describe los formularios 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 en el idioma.

Los formularios marcados con "L" en esta tabla se clasifican como formularios derivados de "biblioteca" en el estándar y, a menudo, se implementan como macros utilizando formas más fundamentales en la práctica, lo que hace que la tarea de implementación sea mucho más fácil que en otros lenguajes.

Si bien beginse define como una sintaxis de biblioteca en R5RS, 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 en el esquema R5RS. 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 en el lenguaje.

Los procedimientos de cadenas y caracteres que contienen "-ci" en sus nombres realizan comparaciones independientes entre mayúsculas y minúsculas entre sus argumentos: las versiones en mayúsculas y minúsculas del mismo carácter se consideran iguales.

Las implementaciones de - y / que toman más de dos argumentos se definen pero se dejan opcionales en R5RS.

Solicitudes de implementación del esquema

Debido al minimalismo de Scheme, el estándar no define muchos procedimientos y formas sintácticas comunes. Para mantener el lenguaje central pequeño pero facilitar la estandarización de las extensiones, la comunidad Scheme tiene un proceso de "Solicitud de implementación de esquema" (SRFI) mediante el cual las bibliotecas de extensiones se definen mediante una discusión cuidadosa de las propuestas de extensión. Esto promueve la portabilidad del código. Muchas de las SRFI cuentan con el respaldo de todas o la mayoría de las implementaciones del Esquema.

Las SRFI con un apoyo bastante amplio en diferentes implementaciones incluyen: [33]

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 integrados y secuencias de comandos . Esto ha resultado en 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 un esquema estándar y portátil 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 e impresión de estilo Lisp para el desarrollo y la depuración. Muchos también compilan programas Scheme en binario ejecutable. También es común el soporte para incrustar código Scheme en programas escritos en otros lenguajes, 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 en C, lo que facilita mucho la incrustación. Además, el compilador de Bigloo se puede configurar para generar código de bytes para la máquina virtual Java (JVM) y tiene un generador de código de bytes experimental para .NET .

Algunas implementaciones admiten funciones adicionales. Por ejemplo, Kawa y JScheme proporcionan integración con clases de Java , y los compiladores de Scheme a C a menudo facilitan el uso de bibliotecas externas escritas en C, hasta permitir la incrustación de código C en el código fuente de Scheme. Otro ejemplo es Pvts, que ofrece un conjunto de herramientas visuales que respaldan el aprendizaje de Scheme.

Uso

El esquema es ampliamente utilizado por varias [35] escuelas; en particular, varios cursos de introducción a la informática utilizan Scheme junto con el libro de texto Estructura e interpretación de programas informáticos (SICP). [36] Durante los últimos 12 años, PLT ha ejecutado 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 Scheme rudimentaria. La antigua clase de introducción a la programación del MIT 6.001 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] Asimismo, la clase introductoria en UC Berkeley , CS 61A, se impartió hasta 2011 íntegramente en Scheme, salvo pequeñas desviaciones hacia Logo para demostrar el alcance dinámico. Hoy en día, 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 de estudios actual todavía se basa en el plan de estudios antiguo y partes de la clase todavía se imparten en Scheme. [39]

El libro de texto Cómo diseñar programas de Matthias Felleisen, actualmente en la Universidad Northeastern, es utilizado por algunos institutos de educación superior para sus cursos de introducción a la informática. Tanto la Universidad Northeastern como el Instituto Politécnico de Worcester utilizan Scheme exclusivamente para sus cursos introductorios Fundamentos de Ciencias de la Computación (CS2500) e Introducción al diseño de programas (CS1101), respectivamente. [40] [41] Rose-Hulman utiliza Scheme en su curso más avanzado de Conceptos de lenguaje de programación. [42] El curso básico de la Universidad Brandeis , Estructura e interpretaciones de programas informáticos (COSI121b), también se imparte exclusivamente en Scheme por el informático teórico Harry Mairson . [43] La clase introductoria de la Universidad de Indiana , C211, se imparte íntegramente en Scheme. Una versión del curso a su propio ritmo, CS 61AS, continúa utilizando Scheme. [44] Los cursos de introducción a la informática en Yale y Grinnell College también se imparten en Scheme. [45] Paradigmas de diseño de programación, [46] un curso obligatorio para los estudiantes de posgrado en informática de la Northeastern University , también utiliza ampliamente Scheme. El antiguo curso de introducción a la informática en la Universidad de Minnesota - Twin Cities, CSCI 1901, también utilizó Scheme como idioma principal, seguido de un curso que introdujo a los estudiantes al lenguaje Java; [47] sin embargo, siguiendo el ejemplo del MIT, el departamento reemplazó 1901 con el CSCI 1133 basado en Python, [48] mientras que la programación funcional se cubre en detalle en el curso de tercer semestre CSCI 2041. [49]

El esquema también se utilizó/fue utilizado para lo siguiente:

Ver también

Referencias

  1. ^ "Influencias: la referencia de Rust". La referencia del óxido . Consultado el 18 de abril de 2023 .
  2. ^ LISP común: The Language, 2.ª ed., Guy L. Steele Jr. Digital Press; 1981. ISBN 978-1-55558-041-4 . "Common Lisp es un nuevo dialecto de Lisp, un sucesor de MacLisp, fuertemente influenciado por ZetaLisp y, hasta cierto punto, por Scheme e InterLisp". 
  3. ^ ab 1178-1990 (Reaff 2008) Estándar IEEE para el lenguaje de programación de esquemas. Número de pieza IEEE STDPD14209, reafirmado unánimemente en una reunión del Comité de Revisión de Estándares (RevCom) de la Junta de Estándares IEEE-SA, 26 de marzo de 2008 (punto 6.3 sobre actas), actas de reafirmación consultadas en octubre de 2009. Este documento está disponible en IEEE para su compra únicamente. , y no en línea al momento de escribir este artículo: 2009.
  4. ^ abcdefghijklmnopqr Richard Kelsey; William Clinger; Jonathan Rees; et al. (Agosto de 1998). "Informe revisado 5 sobre el esquema de lenguaje algorítmico". Computación simbólica y de orden superior . 11 (1): 7–105. doi :10.1023/A:1010051815785. S2CID  14069423 . Consultado el 9 de agosto de 2012 .
  5. ^ ab "R7RS final disponible" (PDF) . 2013-07-06.
  6. ^ abcde Sperber, Michael; Dybvig, R. Kent; Flatt, Mateo; Van Straaten, Antón; et al. (Agosto de 2007). "Informe revisado6 sobre el esquema de lenguaje algorítmico (R6RS)". Comité Directivo del Plan . Consultado el 13 de septiembre de 2011 .
  7. ^ abcd Sussman, Gerald Jay; Steele, Guy L. (1 de diciembre de 1998). "El primer informe sobre el plan revisado". Computación simbólica y de orden superior . 11 (4): 399–404. doi :10.1023/A:1010079421970. S2CID  7704398.
  8. ^ "Implementaciones de R6RS". r6rs.org . Consultado el 24 de noviembre de 2017 .
  9. ^ Abdulaziz Ghuloum (27 de octubre de 2007). "Bibliotecas R6RS y sistema de casos de sintaxis (psintaxis)". Esquema de Ícaro . Consultado el 20 de octubre de 2009 .
  10. ^ Mantener, Andrew W.; Dybvig, R. Kent (noviembre de 2014). "Una representación en tiempo de ejecución de los tipos de registros del esquema". Revista de programación funcional . 24 (6): 675–716. doi : 10.1017/S0956796814000203 . S2CID  40001845.
  11. ^ "Informe revisado ^ 6 sobre el esquema de lenguaje algorítmico, Apéndice E: cambios de idioma". Comité Directivo del Plan. 2007-09-26 . Consultado el 20 de octubre de 2009 .
  12. ^ "Electorado R6RS". Comité Directivo del Plan. 2007 . Consultado el 9 de agosto de 2012 .
  13. ^ Marc Feeley (compilación) (26 de octubre de 2007). "Intenciones de los implementadores con respecto a R6RS". Comité directivo del plan, lista de correo de discusión de r6rs . Consultado el 9 de agosto de 2012 .
  14. ^ ab Will Clinger, Marc Feeley, Chris Hanson, Jonathan Rees y Olin Shivers (20 de agosto de 2009). "Declaración de posición (borrador)". Comité Directivo del Plan . Consultado el 9 de agosto de 2012 .{{cite web}}: Mantenimiento CS1: varios nombres: lista de autores ( enlace )
  15. ^ "Noveno borrador de R7RS disponible" (PDF) . 2013-04-15.
  16. ^ Will Clinger (10 de mayo de 2013). "ampliación del periodo de votación". Comité directivo del lenguaje del esquema, lista de correo de informes del esquema. Archivado desde el original el 21 de julio de 2013 . Consultado el 7 de julio de 2013 .
  17. ^ La implementación del Esquema 48 se llama así porque el intérprete fue escrito por Richard Kelsey y Jonathan Rees en 48 horas (6 al 7 de agosto de 1986. Véase Richard Kelsey; Jonathan Rees; Mike Sperber (10 de enero de 2008). "El Manual de referencia incompleto del esquema 48 para la versión 1.8". Jonathan Rees, s48.org . Consultado el 9 de agosto de 2012 .
  18. ^ ab Gerald Jay Sussman y Guy Lewis Steele Jr. (diciembre de 1975). "Esquema: un intérprete para el cálculo Lambda extendido" (PDF) . Memos de IA . Laboratorio de IA del MIT . AIM-349. hdl : 1721.1/5794 . Consultado el 23 de diciembre de 2021 .
  19. ^ Joel Moses (junio de 1970), La función de FUNCIÓN en LISP, o por qué el problema FUNARG debería llamarse problema ambiental , hdl :1721.1/5854, AI Memo 199, Una metáfora útil para la diferencia entre FUNCIÓN y CITA 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. FUNCIÓN actúa como un revestimiento cerrado o no poroso (de ahí el término "cierre" utilizado por Landin). Por tanto, hablamos de expresiones Lambda "abiertas" (las funciones en LISP suelen ser expresiones Lambda) y expresiones Lambda "cerradas". [...] Mi interés por el problema medioambiental comenzó mientras Landin, que tenía un profundo conocimiento del problema, visitó el MIT durante 1966-67. Luego me di cuenta de la correspondencia entre las listas FUNARG que son los resultados de la evaluación de expresiones Lambda "cerradas" en LISP y los cierres Lambda de ISWIM .
  20. ^ van Tonder, André (1 de enero de 2004). "Un cálculo Lambda para la computación cuántica". Revista SIAM de Computación . 33 (5): 1109-1135. arXiv : quant-ph/0307150 . doi :10.1137/S0097539703432165. S2CID  613571.
  21. ^ Niehren, J.; Schwinghammer, J.; Smolka, G. (noviembre de 2006). "Un cálculo lambda concurrente con futuros" (PDF) . Informática Teórica . 364 (3): 338–356. doi : 10.1016/j.tcs.2006.08.016.
  22. ^ Gerald Jay Sussman y Guy Lewis Steele Jr. (marzo de 1976). "Lambda: el imperativo definitivo". Memos de IA . Laboratorio de IA del MIT . AIM-353. Archivado desde el original (posdata o PDF) el 10 de mayo de 2016 . Consultado el 9 de agosto de 2012 .
  23. ^ Gabriel, Richard P .; Pitman, Kent (1988). "Cuestiones técnicas de separación en celdas de función y celdas de valor". LISP y Computación Simbólica . vol. 1, núm. 1 (publicado en junio de 1988). págs. 81-101. doi : 10.1007/BF01806178 . Consultado el 9 de agosto de 2012 .
  24. ^ ab Philip L. Bewig (24 de enero de 2008). "SRFI 41: Corrientes". Los editores de SRFI, Schemers.org . Consultado el 9 de agosto de 2012 .
  25. ^ William Clinger y Jonathan Rees, ed. (1991). "Informe revisado 4 sobre el esquema de lenguaje algorítmico". Punteros ACM Lisp . 4 (3): 1–55 . Consultado el 9 de agosto de 2012 .
  26. ^ Flatt, Mateo (2016). "Encuadernación como conjuntos de ámbitos". 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.
  27. ^ Jonathan Rees, The Scheme of Things The June 1992 Meeting Archivado el 16 de julio de 2011 en Wayback Machine (posdata), en Lisp Pointers, V (4), octubre-diciembre de 1992. Consultado el 9 de agosto de 2012.
  28. ^ Taylor Campbell (21 de julio de 2005). "SRFI 62: comentarios de expresión S". Los editores de SRFI, Schemers.org . Consultado el 9 de agosto de 2012 .
  29. ^ William D. Clinger (1 de julio de 1999). "SRFI 6: puertos de cadena básicos". Los editores de SRFI, Schemers.org . Consultado el 9 de agosto de 2012 .
  30. ^ 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 .
  31. ^ JW Backus; FL Bauer; J. Verde; C. Katz; J. McCarthy P. Naur; et al. (enero-abril de 1960). "Informe revisado sobre el lenguaje algorítmico Algol 60". Numerische Mathematik, Comunicaciones de la ACM y Revista de la Sociedad Británica de Computación . Consultado el 9 de agosto de 2012 .
  32. ^ Jonathan Rees; William Clinger, eds. (Diciembre de 1986). "Informe revisado (3) sobre el esquema de lenguaje algorítmico (dedicado a la memoria de ALGOL 60)". Avisos ACM SIGPLAN . 21 (12): 37–79. CiteSeerX 10.1.1.29.3015 . doi :10.1145/15042.15043. hdl :1721.1/6424. S2CID  43884422 . Consultado el 9 de agosto de 2012 . 
  33. ^ "Sistemas de esquemas que respaldan las SRFI". Los editores de SRFI, Schemers.org. 2009-08-30 . Consultado el 9 de agosto de 2012 .
  34. ^ 75 implementaciones conocidas de Scheme se enumeran en "scheme-faq-standards". Wiki del esquema comunitario. 25 de junio de 2009 . Consultado el 20 de octubre de 2009 .
  35. ^ Ed Martín (20 de julio de 2009). "Lista de escuelas que utilizan el plan". Schemers Inc. Consultado el 20 de octubre de 2009 .
  36. ^ "Lista de escuelas que utilizan SICP". Prensa del MIT. 1999-01-26 . Consultado el 20 de octubre de 2009 .
  37. ^ Eric Grimson (primavera de 2005). "6.001 Estructura e Interpretación de Programas Informáticos". Material didáctico abierto del MIT . Consultado el 20 de octubre de 2009 .
  38. ^ Alex Vandiver; Nelson Elhage; et al. (Enero de 2009). "6.184 - Los zombis beben con cafeína 6.001". MIT CSAIL . Consultado el 20 de octubre de 2009 .
  39. ^ 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 . Consultado el 17 de diciembre de 2019 .
  40. ^ CS 2500: Fundamentos de informática I, Northeastern University
  41. ^ CS 1101: Introducción al diseño de programas (A05): software del curso, Instituto Politécnico de Worcester
  42. ^ "CSSE 304: Conceptos del lenguaje de programación". Instituto de Tecnología Rose-Hulman .
  43. ^ "Plan de estudios CS121b de primavera de 2021" (PDF) . Universidad Brandeis .
  44. ^ "Inicio". berkeley-cs61as.github.io .
  45. ^ Dana Angluin (otoño de 2009). "Introducción a la Informática (CPSC 201)". El zoológico, Departamento de Ciencias de la Computación de la Universidad de Yale . Consultado el 20 de octubre de 2009 .
  46. ^ "Lecturas del curso CSG107 de paradigmas de diseño de programación". Facultad de Informática y Ciencias de la Información de la Universidad Northeastern. Otoño de 2009 . Consultado el 9 de agosto de 2012 .
  47. ^ Estructura de la programación informática 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).
  48. ^ Descripciones de cursos de clase requerida de CSci y otra información Archivado el 25 de octubre de 2019 en Wayback Machine , Departamento de Ciencias de la Computación, Universidad de Minnesota (consultado el 25 de octubre de 2019)
  49. ^ CSCI 2041: Comité de currículo de CSE del nuevo curso, Universidad de Minnesota (consultado el 25 de octubre de 2019)
  50. ^ Portada de Robin (25 de febrero de 2002). "DSSSL - Lenguaje de especificación y semántica de estilo de documento. ISO/IEC 10179:1996". Portadas . Consultado el 9 de agosto de 2012 .
  51. ^ " El principal lenguaje de secuencias de comandos para GIMP que se le ha adjuntado hoy es Scheme ". De Dov Grobgeld (2002). "Tutorial del esquema básico de GIMP". El equipo GIMP . Consultado el 9 de agosto de 2012 .
  52. ^ Todd Graham Lewis; David Zoll; Julián Missig (2002). "Preguntas frecuentes sobre GNOME de Internet Archive". El equipo de Gnome, gnome.org. Archivado desde el original el 22 de mayo de 2000 . Consultado el 9 de agosto de 2012 .
  53. ^ "gnomo astuto". Fundación de Software Libre . Consultado el 9 de agosto de 2012 .
  54. ^ Laurence Brevard (9 de noviembre de 2006). "Actualización del programa Synopsys MAP-inSM: Foro de desarrolladores de interoperabilidad de EDA" (PDF) . Sinopsis Inc. Consultado el 9 de agosto de 2012 .
  55. ^ Kawai, Shiro (octubre de 2002). "Pegando cosas: esquema en la producción de contenido CG en tiempo real". Actas de la Primera Conferencia Internacional Lisp, San Francisco : 342–348 . Consultado el 9 de agosto de 2012 .
  56. ^ 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 investigación de Google . Consultado el 9 de agosto de 2012 .

Otras lecturas

enlaces externos