Closed dfmorrison closed 8 years ago
Fair point, this should be further clarified and improved. I will also add some documentation.
Short answer:
Your confusion is somewhat due to my lazyness: The current handling of read-time constant of structure-object
is not properly implemented. The implementation is here.
For matching against structure-object
, use the structure
pattern such as (structure frob :blah 1 :blech 2)
(or in shorthand, (frob :blah 1 :blech 2)
) for the consistent behavior: Numbers and characters are compared by eql
.
Long answer:
The comparison criteria in trivia is not identical to either equal
nor equalp
. The philosophy in trivia follows:
equalp
). (1)number
or character
, they are compared by eql
, not =
or char-equal
as in equalp
. The motivation is that ANSI CL has eql
type specifier and the lisp implementation can recognize these types for optimization. (2)eq
(does not descend into name
and package
of the symbol). (3)Your last example matches against a read-time constant #S(FROB :BLAH 1 :BLECH 2)
. If trivia applied eq/eql/equal to this comparison, It does not make sense because you can't generate the same (by eq/eql/equal) instance of FROB
in run time. Same thing applies to #(1 2 3)
: you can't generate the same instance in run-time. Note that for structure-object
and array
, equal
uses eq
.
(trivia:match obj
(#(1 2 3) t))
;; ^^^^^ this array is instantiated in read-time and
;; you cant generate the same instance by `eq`
Thus, read-time literals of vector
which have appeared in the patterns are converted into vector
patterns, and the matcher descends into the contents. Elements are compared by eql
.
(trivia:match obj
((vector 1 2 3) t))
;; ^^^^^ compiled into vector pattern
However, currently, read-time literals of structure-object
are not converted into structure
patterns and instead I abused equalp
pattern. This makes some comparisons done by =
and char-equal
. Thus, for a consistent behavior which always uses eql
, write structure
pattern, not the read-time literals #S(...)
.
(trivia:match obj
(#S(FROB :BLAH 1 :BLECH 2) t))
;; current compilation
(trivia:match obj
((equalp #S(FROB :BLAH 1 :BLECH 2)) t))
;; ideal compilation
(trivia:match obj
((structure FROB :BLAH 1 :BLECH 2) t))
Hi, it's fixed now. Closing.
I mean the read-time structure-object
literals are converted into structure
patterns.
My apologies if there is a mailing list or some such that's better suited than this for asking questions: I looked but failed to find one.
Anyway, I looked in the documentation, and failed to find an answer to this; my apologies if it's there and I just missed it.
When comparing constants what sort of equality is used? The following would seem to imply
equal
is being used:So does this:
(Note that in this implementation (CCL):
)
But this seems to imply
equalp
is being used instead:As does this:
Does it depend on the types involved? Of the thing being matched or of the pattern? And, if so, in which cases are what being used? Of, if it's something else, what, please? Or am I just confused, which is perfectly plausible.