¿En qué se diferencia Racket de Scheme?


184

Racket es un descendiente de Scheme. ¿En qué se diferencia Racket de R6RS? ¿Qué agregó, quitó o simplemente es diferente?

Entiendo que Racket es más que un idioma, es una plataforma para idiomas. Pero me estoy refiriendo al dialecto principal de Racket.

Respuestas:


132

Racket se basa en última instancia en R5RS, y no en R6RS y no en un estricto superconjunto de ninguno de los dos. No creo que se pueda llamar 'Esquema' porque no es compatible con cualquier estándar de Esquema.

La mayoría de las implementaciones ofrecen extensiones, pero por lo demás son compatibles con versiones anteriores, por supuesto, el compilador que viene con Racket también puede ejecutarse en modo R5RS o R6RS. El esquema R5 / 6RS válido que se ejecuta en modo raqueta puede ser rechazado, causar errores de tiempo de ejecución o comportarse de manera diferente de lo que debería. Dicho esto, los puntos principales donde no es compatible con versiones anteriores son:

  • Racket tiene no set-cdr!y set-car!, más bien, set-mcar!que solo funciona en pares creados específicamente como mutables.
  • Lo que Racket llama letrecse llama letrec*en R6RS y no existe en R5RS, lo que R5RS y R6RS llaman letrecno existe en Racket.
  • En Racket, muchas cosas se autoevalúan, lo que generaría un error en R5RS, lo más importante, la lista vacía .
  • La raqueta distingue entre mayúsculas y minúsculas, aunque R6RS también distingue entre mayúsculas y minúsculas
  • La raqueta trata ( ... )y, [ ... ]como equivalente, R5RS no, pero R6RS sí.

Probablemente haya más, pero en la mayoría de las otras partes, la raqueta es un superconjunto de Scheme.


24
En Racket ()no es válido, no se autoevalúa. Además, la raqueta hace haber más restringido letrec- por ejemplo, el de la r5rslengua; Es una elección intencional utilizar la letrec*versión similar en el idioma predeterminado.
Eli Barzilay

9
@ Eli, whoops, tienes razón, la raqueta que se ejecuta en modo Swindle parece considerar ()autoevaluarse, estaba confundido con ese. Sin ()embargo, nunca entendí por qué no estaba autoevaluando en Scheme como lo es en Common Lisp
Zorf

@Zorf Sin embargo, se puede cambiar fácilmente sobrecargando #%app:#lang racket (require (rename-in racket [#%app old])) (define-syntax #%app (syntax-rules () [(_) '()] [(_ . rest) (old . rest)])) (null? ()) ;; => #t
Suzanne Dupéron el

2
Esta respuesta debe ser actualizada. El conjunto de características de Racket supera con creces el de Scheme ahora, con módulos y definiciones de lenguaje, etc.
CinchBlue

1
@MaliRemorker No entiendo exactamente lo que quieres decir, pero Scheme está actualmente en R7RS y estaba en R6RS. Pero Racket todavía supera el conjunto de características R6RS.
CinchBlue

36

Contiene listas inmutables, como se mencionó anteriormente. También contiene un sistema de estructura que es un poco más limpio que el sistema de registro R6RS. Tiene una clase orientada a objetos y un sistema de objetos. Tiene soporte nativo para el diseño por contrato. Tiene un sistema de unidades que recuerda al sistema de módulos ML, así como un sistema de módulos muy similar al sistema de módulos R6RS. Estoy seguro de que he olvidado tantas cosas como he mencionado.

No estoy seguro de que el cambio de nombre fuera útil como algo más que un truco de marketing, pero la raqueta es definitivamente un dialecto distinto del esquema.


24
Creo que el cambio de nombre se debió a que no querían ser un dialecto de Scheme con un montón de adiciones no estándar; querían ser un lenguaje basado en Scheme con un montón de cosas más estándar. Clasificar el esquema PLT como "solo" un dialecto del esquema es como clasificar a Ruby como un dialecto de Mirah: no es inexacto, pero minimiza las fortalezas del lenguaje.
Chuck

55
Creo que usar un nombre diferente es una decisión acertada: usar el mismo nombre para diferentes idiomas que tienen un origen común es confuso de la OMI. Cambiaría el nombre incluso si el lenguaje contuviera Scheme como un subconjunto pero contuviera tantas adiciones que alentaría un estilo de programación muy diferente.
Giorgio


18

La especificación del lenguaje R5RS en el lenguaje de programación Scheme se basa en el consenso entre los múltiples implementadores del Scheme. Esto implica que el lenguaje es muy estable. También implica que muchas características útiles no son parte del estándar R5RS.

Racket se ha basado en R5RS y lo ha ampliado enormemente. Algunas extensiones se definen como macros, pero algunas características requieren el soporte del sistema de tiempo de ejecución.

Características en Racket no implementables solo por macros:

  • continuaciones delimitadas (más generales que call / cc)
  • marcas de continuación
  • hilos
  • lugares
  • ffi

El módulo y el sistema macro son mucho más generales que la especificación RnRS. Junto con la #langespecificación de lector / idioma, es posible definir idiomas personalizados (con sintaxis personalizada) y usarlos con programas normales de Racket.

En algunos casos, Racket tiene construcciones cuyo comportamiento se desvía de R5RS. La más obvia es hacer que consconstruir un par inmutable ( mconsconstruya un par mutable). Una ventaja de tener pares inmutables es que lengthahora se ejecuta en O (1) tiempo amortizado.


2
... pero hace que la lista O (1) sea imposible de agregar.
Will Ness

16

Racket incluye muchas construcciones de lenguaje realmente agradables no incluidas en el esquema R6RS, como "match" .


3
¿Por qué "emparejar" sería una buena característica? Al menos, cuando expresa una opinión, debe dar una breve explicación de la misma, de modo que las personas que no estén familiarizadas con Racket puedan entender por qué "emparejar" es teóricamente beneficioso.
nbro

1
La coincidencia de patrones es una característica realmente deseada en muchos lenguajes con fondos de programación funcionales, desafortunadamente ni siquiera R6RS o Common Lisp implementa esto por defecto, así que sí, esta es una característica realmente agradable y diferencial que proporciona Racket. Por ejemplo, lenguajes como Haskell, Elixir, Rust y F # proporcionan ese tipo de construcciones y son muy utilizados. Personalmente hago la programación de Lisp principalmente en Common Lisp y extraño en muchos casos la falta de implementación de coincidencia de patrones.
Manoel Vilela

1
matches muy agradable, pero afortunadamente es solo una macro, por lo que se puede agregar fácilmente a Lisps que no lo tiene. Common Lisp puede hacer coincidir patrones de luz en las listas a través de destructuring-bind. Es simple escribir una destructuring-casemacro basada en ella, y muchas personas lo han hecho. Para Scheme hay matchbibliotecas portátiles . Clojure tiene core.match.
Lassi

Las macros pueden hacer que el código sea difícil de leer ya que a menudo tienen una semántica especial, por lo tanto, el lenguaje siempre debe estandarizar todas las macros de propósito general para que todos no construyan sus propias macros. La coincidencia de patrones debe ser la predeterminada, como en Arc & Clojure & Racket & Ocaml & Haskell, ya que especifica más directamente la intención. Caddr tiene un nivel demasiado bajo.
aoeu256

12

Para un gran ejemplo, las listas de Racket son inmutables por defecto, mientras que las de Scheme son mutables. Racket también incluye muchas bibliotecas estándar (p. Ej., Servidor web) que otros Esquemas no incluyen.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.