2010-05-14 10 views
5

R5RS da propuso definiciones de macros para la biblioteca de formularios de la sintaxis:¿Qué, si hay alguno, está mal con esta definición de letrec en Scheme?

http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-10.html#%_sec_7.3

que también define letrec, de una manera muy complicada, ciertamente no cómo lo definiría, me basta con utilizar:

(define-syntax letrec2 
    (syntax-rules() 
    ((letrec2 ((name val) ...) body bodies ...) 
    ((lambda() 
     (define name val) ... 
     body bodies ...))))) 

Por lo que entiendo la semántica de letrec, que utilizo muy a menudo como un nombre let. Funciona de esta manera, sin embargo, como he tenido una buena cantidad de debates con filósofos que piensan que pueden refutar la relatividad especial o las teorías fonológicas establecidas, sé que cuando piensas que tienes una solución simple para un problema complejo, es probable que INCORRECTO. Tiene que haber algún punto donde esta macro no satifique la semántica de letrec, de lo contrario probablemente lo habrían usado.

En esta definición, las definiciones son locales para el cuerpo del letrec, pueden referirse mutuamente para la recursión mutua, no estoy muy seguro de qué (si hay alguna) es incorrecta.

Respuesta

0

Bien, finalmente encontré la razón, es tan simple como inútil, hay no hay nada de malo en mi definición, y de hecho se debe a algunos errores superiores a los del R5RS.

http://community.schemewiki.org/?scheme-faq-macros

Busque 'letrec', que no todo podría haber respondido a mi pregunta de lo que estaba mal, que no pasaba nada, aparentemente, R5RS tenía una 'fe de erratas' en una sección informativa al parecer. Voy a ser forzado a aceptar mi propia respuesta ahora supongo ...

Lo que me pregunta ahora es por qué los autores del R5RS no eligieron esta solución simple y fueron por una muy compleja que incluso contenía un error. ..

+0

Citando conmigo: "La definición interna es una forma primitiva solo en algunas implementaciones". Citando schemewiki: "Aún así, hay algunas implementaciones de Scheme que solo proporcionan una definición primitiva de nivel superior e implementan las definiciones internas en términos de letrecs ..." Su definición solo funciona en algunas implementaciones. Cité la introducción a R5RS para mostrar por qué creo que los autores de R5RS no eligieron su implementación. Si mi punto acerca de la filosofía de R5RS no tiene sentido, estoy dispuesto a responder sus preguntas al respecto. – Davorak

+0

@Davorak Bueno, técnicamente la definición * funcionará * en todas las implementaciones. Es solo que en algunas implementaciones el 'define' interno que usa se expandirá a la implementación nativa de' letrec'. – dubiousjim

5

Me parece que ha llevado la responsabilidad de la implementación de la macro al compilador, algo que los diseñadores de R5RS parecen estar tratando de evitar.

De hecho, las definiciones locales se implementan con letrec en R5RS. Ver 6.2.2 Internal definitions.

creo que las intenciones de los diseñadores se resumen bien en los introduction to the R5RS: idiomas

La programación debe ser diseñada no por la función en la parte superior de la función de pilotaje, pero quitando los debilidades y restricciones que hacen adicional las características parecen necesarias. Esquema demuestra que un muy pequeño serie de reglas para formar expresiones, sin restricciones en la forma en que se componen, es suficiente para formar un lenguaje de programación práctica y eficiente que sea lo suficientemente flexible como para apoyo mayoría de los principales programas paradigmas en uso hoy.

edit1: Ejemplo de interno define la versión transformada a r5rs de letrec. esquema PLT 4.2.5 recoge/R5RS/main.ss

(define-syntax (r5rs:body stx) 
(syntax-case stx (let) 
    [(_ (let() . body)) 
    #'(let() . body)] 
    [_ 
    ;; Convert internal definitions to `r5rs:letrec', as opposed 
    ;; to `letrec'. 
... 

En el Esquema PLT en modo R5RS no convertir define internos a la versión R5RS de letrec. También puede probar esto usted mismo mediante el macroextensor de DrScheme en cualquier código con definiciones internas.

+0

Bueno, define es una forma primitiva, no una forma de biblioteca a diferencia de letrec. definir y configurar! realmente no se puede definir en términos de otras funciones. Además, por lo demás, realmente no entiendo cómo se relaciona su publicación con mi punto aquí, todavía lo tengo como macro. Y letrec es parte del estándar R5RS, aunque es posible que una implementación se dé cuenta de esto como una macro, no es necesario, siempre que se cumpla la semántica dada en R5RS. Y todavía es una macro aquí, las macros en R5RS son 'sugerencias'. – Zorf

+0

@Lajla La definición interna es una forma primitiva solo en algunas implementaciones. Internal define can y se define en términos de letrec en algunas implementaciones. Su macro solo funciona para definir letrec cuando la definición interna es primitiva. La definición interna a menudo se define en términos de letrec porque sigue la filosofía que cité desde la introducción de R5RS. – Davorak

+0

¿Tiene alguna cita que indique eso? Porque si eso es cierto, esa sería obviamente la explicación. Pero, por lo que sé, definir es siempre primitivo porque tiene una semántica completamente única, como en, no puede aparecer en muchos lugares, y para definir definiciones internas en términos de macros, una implementación necesitaría agregar letrec-sintaxis a cada forma que tiene un cuerpo. Su fuente solo dice que es equivalente, no es explícito sobre cómo se implementa, pero si puede proporcionar una cita a una implementación que hace esto, entonces es la respuesta obvia a nuestro problema. – Zorf

0

Buena pregunta.

Creo que el problema con una secuencia de define es la siguiente:

"El orden de evaluación de los una expresión expr ...no está especificada, por lo que un programa no debe evaluar una referencia a ninguna de las variables obligados por la expresión letrec antes todos los valores se han calculado"

aquí: http://www.scheme.com/tspl4/binding.html#./binding:s20

+0

Pero esto es lo que hacen las definiciones internas (y externas) si no me equivoco. Es por eso que pueden referirse libremente entre sí y recurrir mutuamente. También probé todas las operaciones básicas como un factorial local, recíprocamente recíproco, incluso? e impar? funciones, definiendo un nombre-let en términos del letrec2, permitiéndoles formar cierres sobre su entorno léxico que parece funcionar. Estoy bastante perdido. Además, el estándar R5RS parece estar definido para este enfoque, ya que en, las funciones definidas en letrec pueden acceder a las funciones definidas, pero no a otros valores a menos que se definan explícitamente en el letrec. – Zorf

+0

Creo que estás equivocado. Las definiciones externas e internas son diferentes entre sí en R5RS. Para las definiciones externas: (definir a b) (definir b 2) es un error de sintaxis para la primera definición ya que b aún no está definido. Para interno define o letrec (letrec ((ab) (b 2) a) -> # y no debe ser un error de sintaxis. Lo mismo con ((lambda() (definir ab) (definir b 2) a)) -> # Davorak

+0

Hmm, quería ser más explícito pero tenía muy pocos caracteres, sí, es un error de sintaxis, pero: (define a (lambda (x) (+ (b 2) x))) (definir b (lambda (x) (+ 1 x))) no. Como dije, no pueden acceder a valores no definidos anteriormente, pero pueden acceder a funciones que se definirán más adelante. Esto es idéntico en externo e interno define y (a2) evalúa el resultado esperado de 5 en este ejemplo. Por eso planteé el argumento de que la semántica de letrec parece haberse adaptado a las definiciones internas, ya que letrec dice explícitamente que solo puede referirse a funciones, no a valores . – Zorf

3

estados R5RS que la semántica de letrec son exactamente los mismos que los de las definiciones internas the section devoted to the latter Ver para más detalles; cito el fragmento clave a continuación:.

A <cuerpo> que contiene definiciones internas siempre se puede convertir en una expresión letrec completamente equivalente.

Definir así letrec en términos de definición interna simplemente cambia el problema.

Además, me resulta más fácil de definir una macro letrec y tienen lambda define internos desugar en letrec que rellenar todo ese código complejo en el manejador de lambdaletrec y construir encima de eso. Eso sin tocar la cuestión de cuál es la forma más bonita de introducir enlaces mutuamente recursivos en un alcance no de nivel superior ... ;-)

Cuestiones relacionadas