At first glance this looks like an easy problem. But actually building the different parse trees for what I would expect here, and in all cases it should be True.
So that is to say:
a == (b is c) --> ==
/ \
a is
/ \
b c
(a == b) is c --> is
/ \
== c
/ \
a b
a == b is c --> ==_is
/ | \
a b c
Assuming that the == and is are operator tokens and a, b, c are operands, that seems to be one rational hypothesis.Another hypothesis is that == and is are not pure functions that operate on values, but are special operators that operate on syntax, and treat a parenthesized expression differently from an unparenthesized one.
(In what way does this sort of thing belong in a self-proclaimed newbie-friendly language? This has to be a bug.)
If you're working in TXR Lisp, you can use the meq, meql and mequal functions for three or more argument equality.
The call:
(meq a b c ...)
does not mean anything similar to: (and (eq a b) (eq b c) ...)
but the semantics (except for operand evaluation) is like: (or (eq a b) (eq a c) (eq a d) ...)
and likewise for the other two. It's testing whether the left argument is equal to at least one of the remaining arguments.These functions can be called with only one argument, in which case they yield false, just like (or).
These functions are very useful in cond statements that include some tests that prevent conversion into caseq/caseql/casequal.
(cond
((meql x 1 2 3) ... ) ;; x is one of 1 2 3
((> x 10) ...) ;; x is greater than 10
(t ...)) ;; otherwise
m stands for "multi"; or, if you like, it stands for "member" because (meql x a b c) replaces (memql x (list a b c)).