2011-07-11 17 views
7

No soy un experto en Scheme, así que no estoy seguro si estoy usando la terminología correcta aquí. Deje que el código hable por sí mismo:Símbolos citados en el Esquema

CSI> (define tree '(1 2 3 'Symb 4 5 6)) 
#<unspecified> 
CSI> tree 
(1 2 3 (quote Symb) 4 5 6) 
CSI> (symbol? 'Symb) 
#t 
CSI> (map symbol? tree) 
(#f #f #f #f #f #f #f) 

Viniendo de fondo Clojure, pensé símbolos fueron utilizados como esto en el esquema, como palabras clave en Clojure. Se supone que debo pasar por una estructura de lista anidada y reemplazar símbolos con una llamada a función. Esta es mi solución unidimensional y que funciona:

(define (print-track track attrs) 
    (apply fmt #t 
     (map (lambda (attr) 
       (cond 
        ((symbol? attr) (get-attr attr track)) 
        (else   attr))) 
      attrs))) 

El espacio vacío por encima de la línea de (symbol?) era para un (list?) condicional, pero es probable que el abordaje equivocado.

Estoy usando Chicken Scheme.

Respuesta

18

Te has encontrado con la cita de Lisp "gotcha". En Scheme, los símbolos se utilizan para referencia de variable, que obviamente comprende. Esto se evalúa como verdadero:

> (symbol? 'Symb) 

porque citó el símbolo y evitó que se usara como referencia de variable.

> (symbol? Symb) 

Primero buscaría el valor de la variable Symb, y luego verificaría si ese valor era un símbolo.

> (let ((Symb 'foo)) (symbol? Symb)) 

Evaluaría a #t, ya que el valor de Symb es un símbolo: foo.

> (let ((Symb 7)) (symbol? Symb)) 

, por supuesto, evaluar a #f.

Pareces haber tropezado con un matiz de presupuesto.

'Symb 

es en realidad la taquigrafía; es equivalente a

(quote Symbol) 

que, una vez más, devuelve su argumento no evaluado.

Pero su código no necesita el presupuesto interno. Cuando

> (define tree '(1 2 3 'Symb 4 5 6)) 

se cita toda la lista; nada dentro de la lista va a ser evaluado. Es por eso que

> tree ; => (1 2 3 (quote Symb) 4 5 6) 

Dentro de la lista citada, 'Símb es equivalente a (cita Símb), que en realidad es una lista. Como se cita toda la lista, usar Symb sin comillas no se tratará como una referencia de variable. Simplemente sería el símbolo.

> (define tree '(1 2 3 Symb 4 5 6)) 
> tree ; => (1 2 3 Symb 4 5 6) 

Ahora, si estuviera pasando todos los argumentos para la función de lista, lo que originalmente qué sería correcto:

> (define tree (list 1 2 3 'Symb 4 5 6)) 
> tree ; => (1 2 3 Symb 4 5 6) 

En ese caso, estás pasando los argumentos a una función; los argumentos a una función se evalúan, por lo que necesita una cita para evitar que los símbolos se traten como referencias de variables.

> (define tree (list 1 2 3 (quote Symb) 4 5 6)) 

Haría lo mismo.

+0

+1 por claridad, minuciosidad – acfoltzer

+1

Realmente no se puede escribir ninguna respuesta más clara que esta :) – progo