Symbols and Symbolic Computation

Common Lisp symbols carry more: a name, a package, a value cell, a function cell, and a property list. Keywords (:name) evaluate to themselves. Clojure has both symbols ('foo) and keywords (:foo), and keywords are also functions that look themselves up in maps: (:name {:name "Ana"}).

'apple                                  ; a symbol
(symbol? 'apple)                        ; #t
(eq? 'apple 'apple)                     ; #t: symbols are interned (unique)
(symbol->string 'apple)                 ; "apple"
(string->symbol "banana")               ; banana
(gensym)                                ; a fresh, unique symbol (Racket: gensym)

;; Symbols make great data: no need for enums or string constants
(define (traffic-light-next color)
  (case color
    ((red) 'green)
    ((green) 'yellow)
    ((yellow) 'red)))

;; Symbolic data: expressions as lists of symbols
(define expr '(+ (* 2 x) 3))
(define (substitute expr var val)
  (cond ((eq? expr var) val)
        ((pair? expr) (map (lambda (e) (substitute e var val)) expr))
        (else expr)))
(substitute expr 'x 5)                  ; (+ (* 2 5) 3)
(eval (substitute expr 'x 5) (interaction-environment))   ; 13 (R7RS eval with an environment)