Search code examples
switch-statementschemequoteguile

Strange comparison of `'quote` and `'lambda` in Scheme (guile)


Let see my code

Code1:

(eqv? 'lambda 'quote)

return #f

Code2:

(case 'lambda ('quote "equal") (else "not equal"))

return "not equal" but generate a warning ;;; <stdin>:17:0: warning: duplicate datum quote in clause ((quote quote) "equal") of case expression (case (quote lambda) ((quote quote) "equal") (else "not equal"))

Code3: strange result

 (case 'quote ('lambda "equal"))

return "equal" and without warning

I interpreted code using guile (GNU Guile) 2.0.11. And here is the description of case syntax from gnu

The the result of this evaluation is compared against all datums using eqv?


Solution

  • '<something> is an abbreviation for the list (quote <something>). In Scheme, the case form should be a list (in some Lisps, e.g., Common Lisp, it can also be a single non-list element, representing the list of just that element), so that you can do, e.g.:

    (case n
      ((0) 'zero)                 ; in Common Lisp, could also be (0 'zero)
      ((1 2 3) 'one-two-or-three)
      ((4 5) 'four-or-five))
    

    When you do:

    (case some-symbol
       ('quote 'it-was-quote))
    

    You're doing

    (case some-symbol
      ((quote quote) 'it-was-quote))
    

    So you're providing a list, and it's got a duplicate element. There's nothing wrong with that, but it's usually unexpected, and so you get a warning.

    By that reasoning

    (case 'quote ('lambda "equal"))
    

    is the same as

    (case 'quote ((quote lambda) "equal"))
    

    and, since the symbol quote is in the list (quote lambda), the case matches, and you get "equal". The moral of the story is: "don't quote the cases in case." That is, you should be doing:

    (case 'quote
      ((lambda) "equal"))