Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symbols quoted in Scheme

Tags:

clojure

scheme

I'm no Scheme expert so not sure if I'm using the correct terminology here. Let the code speak for itself:

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)

Coming from Clojure background, I thought symbols were used like this in Scheme, like keywords in Clojure. I'm supposed to go through a nested list structure and replace symbols with a function call. This is my onedimensional solution and it does work:

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

The empty space above the (symbol?) line was for a (list?) conditional, but it's likely the wrong aproach.

I'm using Chicken Scheme.

like image 512
mike3996 Avatar asked Jul 11 '11 13:07

mike3996


People also ask

What is a symbol in scheme?

Symbols in Scheme are widely used in three ways: as items of discrete data, as lookup keys for alists and hash tables, and to denote variable references. Looking beyond how they are written, symbols are different from strings in two important respects. The first important difference is uniqueness.

How do you quote in a scheme?

Scheme provides a cleaner way of writing quote d expressions, using the special single-quote character ' . Rather than writing out (quote some-expression ) , you can just precede the quoted expression with the single-quote character. For example, we can write the same definition of foo as (define foo '(1 2 3)) .

What is comma in scheme?

If a comma appears followed immediately by an at-sign (@), then the following expression must evaluate to a list; the opening and closing parentheses of the list are then "stripped away" and the elements of the list are inserted in place of the comma at-sign expression sequence.


1 Answers

You've run into the Lisp quote "gotcha". In Scheme, symbols are used for variable reference, which you obviously understand. This evaluates to true:

> (symbol? 'Symb)

because you quoted the symbol, and prevented it from being used as a variable reference.

> (symbol? Symb)

Would first look up the value of the Symb variable, and then check if that value was a symbol.

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

Would evaluate to #t, since the value of Symb is a symbol: foo.

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

Would, of course, evaluate to #f.

You seem to have tripped on a nuance of quote.

'Symb

is actually shorthand; it's equivalent to

(quote Symbol)

which, again, returns its unevaluated argument.

But your code doesn't need the inner quote. When you

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

the entire list is quoted; nothing inside of the list is going to be evaluated. That's why

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

Inside of the quoted list, 'Symb is equivalent to (quote Symb), which is actually a list. Since the whole list is quoted, using Symb unquoted would not be treated as a variable reference. It would just be the symbol.

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

Now, if you were passing all those arguments to the list function, what you originally did would be correct:

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

In that case, you're passing those arguments to a function; arguments to a function are evaluated, so you need quote to prevent symbols from being treated as variable references.

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

Would do the same thing.

like image 99
Daniel Ralston Avatar answered Sep 21 '22 13:09

Daniel Ralston