2010-03-06 9 views
8

¿No es posible tratar las funciones en Scheme como cualquier otra lista?Función de esquema de desplazamiento como una lista

Básicamente, lo que quiero hacer para es algo como esto:

(define (foo) "hello") 

(cdr foo) ; or similar, should return the list ((foo) "hello") 

que he encontrado a similar discussion sobre esto, y me siento un poco decepcionado si esto no es posible con el Esquema. Si es así, ¿por qué es esto imposible? ¿Es posible en otros ceceos?

EDITAR: Cambió (cdr 'foo) a (cdr foo) - fue engañoso. Estoy preguntando, ¿por qué no puedo acceder a una función como una lista?

+0

encontró también algunas notas interesantes: http://www.cs.brown.edu/ pipermail/plt-scheme/2006-May/013052.html – csl

Respuesta

3

tengo a menudo quería poder hacer lo mismo csl. A continuación hay un ejemplo rápido de cómo hacer esto en mzscheme.

DrScheme 4,2

(module qdefine mzscheme 
    (provide ;(all-from-except mzscheme let) 
    (rename define olddefine) 
    (rename quote-define define) 
    (rename quote-cdr cdr) 
    (rename quote-car car)) 

    (define define-list '()) 
    (define define-list-add 
    (lambda (key value) 
     (set! define-list (cons `(,key ,value) define-list)))) 

    (define-syntax quote-define 
    (syntax-rules() 
     ((_ (pro-name args ...) body ...) 
     (begin 
     (define (pro-name args ...) body ...) 
     (define-list-add pro-name '((pro-name args ...) body ...)))) 
     ((_ pro-name pro) (begin 
          (define pro-name pro) 
          (define-list-add pro-name 'pro))) 

    )) 

    (define quote-cdr (lambda (lst) 
         (if (procedure? lst) 
          (cdr (cadr (assoc lst define-list))) 
          (cdr lst)))) 

    (define quote-car (lambda (lst) 
         (if (procedure? lst) 
          (car (cadr (assoc lst define-list))) 
          (car lst)))) 
) 
(require 'qdefine) 

(define testfunc (lambda (args) args)) 
(cdr testfunc) 
(car testfunc) 

(define (testfunc2 test) 'blah) 
(cdr testfunc2) 
(car testfunc2) 

(define testlist '(1 2 3 4 5 6 'a)) 
(cdr testlist) 
(car testlist) 

Salidas:

((args) args) 
lambda 
('blah) 
(testfunc2 test) 
(2 3 4 5 6 'a) 
1 
> 
+0

Fantástico, funciona genial en mzscheme 4.2.4 – csl

+0

¿Alguien sabe cómo hacerlo en otras implementaciones de esquemas? – csl

+1

Según la implementación, creo que puede hacer algo similar con defmacro o cierres sintácticos. Me gustaría tener el macro equivalente de (definir blah (lambda ...)) (definir blah (lambda (...) nuevo código (blah ...))), pero no he encontrado una implementación de esquema que permita para una manera directa de hacer esto. – Davorak

1

'foo evalúa a un símbolo, no puede tomar el CDR de un símbolo.

Lo que puede querer hacer es (cdr foo), pero esto no funciona. El valor de un FOO es un procedimiento, no una lista.

+0

Sí; Estoy preguntando _por qué_ no puedo leer un procedimiento. – csl

+0

porque el procedimiento no es una lista. Usted puede cdr solo listas. el procedimiento podría ser un montón de instrucciones de la máquina. –

+0

No es una respuesta muy satisfactoria; podría decirse lo mismo de las listas, porque realmente no sabe cómo se representan las listas en la memoria. – csl

1

Usted puede ser capaz de acceder a la función como una lista usando pp o pretty-print. Dicho esto, es posible que también deba ejecutar su código en modo de depuración. Sin embargo, esto depende de la implementación. Sé que puede funcionar en Gambit-C.

2

Su formulario define no es una función sino una definición de función. De hecho, es una forma abreviada de

(define foo 
    (lambda() 
    "hello")) 

Lambda puede ser pensado como una "invocación del compilador". En este caso, produce una función que devuelve esa cadena. Define luego vincula esta función al símbolo 'foo.

comparar esto con

(define foo "hello") 

que se une sólo la cadena en el símbolo 'foo. ¿Qué devolvería (cdr foo)?

Ahora, es imaginable que alguna implementación de esquema realmente guarde o tenga la opción de guardar el formulario lambda al vincular una función a un símbolo. Deberá verificar la documentación, pero el tipo de interpretación pura que esto implica seguramente tendría un impacto en el rendimiento.

Si logras esto, sin embargo, se le devolverá el formulario lambda, no la forma define.

+0

Excelente explicación! ¿No sería posible crear mi propia forma de definición que compilara el código (a través de eval) y mantuviera la fuente alrededor? Eso sería útil. – csl

1

(define (foo) ...) produce un objeto compilado, y es un valor - un procedimiento.
No puede iterar sobre él porque no es s-expresión.

Al igual que otros sugeridos, debe consultar su entorno de programación y ver
si tiene alguna función para tales tareas.

2

MIT Scheme tiene la capacidad de hacer esto. (Si realmente lo desea, coméntelo y le daré el código. Tenía que encontrar algunas funciones no documentadas para hacerlo realidad.)

Sin embargo, no está en la definición del lenguaje del esquema, por lo que las implementaciones no tienen que permitirlo. La razón de esto es que para hacer las funciones más rápidas, una buena implementación del Esquema modificará las funciones. Esto significa reescribirlos en un idioma diferente (ya sea un código de máquina o algo de un nivel bastante bajo) y eliminar los bits que no necesite; por ejemplo, la función + debe comprobar en general si sus argumentos son números, y si es así , qué tipo de números, pero si su función es un bucle que llama al +, puede verificar una vez al principio y hacer que la función sea mucho más rápida.

Por supuesto, todavía podría mantener las listas sin demasiados problemas, incluso con todas estas cosas. Pero si intentaste modificar las listas, ¿cómo funcionaría?

(Una vez más, se puede hacer que funcione. Sólo sería más trabajo para los ejecutores, y puesto que no se utiliza por lo general en los programas, la mayoría de la gente probablemente no quiero molestar.)

+0

Claro, me gustaría obtener el código. Tal vez publicarlo en línea (gist/pastebin)? – csl

+1

Lo siento, pensé que lo tenía, pero solo lo busqué y no pude encontrarlo. Lo logré descargando básicamente las fuentes de mit-scheme, descubriendo cómo representaban los procedimientos interpretados y usando algunas de las funciones en ese archivo que estaba disponible en el REPL, aunque probablemente no deberían haberlo sido. –

2

En astucia,

guile> (define (foo bar) 'baz)
guile> (Procedimiento-fuente foo)
(lambda (barra) (cotización baz))
guile> (CDR (foo procedimiento de código))
((bar) (Baz cita))
astucia>

Cuestiones relacionadas