-
Notifications
You must be signed in to change notification settings - Fork 22
Known Differences
In this page, we describe the known differences between Trivia and Optima.
In Optima, constant patterns are defined as follows:
A constant-pattern matches the constant itself.
Examples:
(match 1 (1 2)) => 2
(match "foo" ("foo" "bar")) => "bar"
(match '(1) ('(1) 2)) => 2
We took a rather radical interpretation of this specification, allowing the symbols in the structural constants (arrays, structs) to be parsed as patterns. For example,
(match #(0 1 2)
(#(_ b 2) b))
;; -> 1
(match #2A((0 1 2) (3 4 5))
(#2A((_ b 2) (_ _ f)) (+ b f)))
;; 1+5 -> 6
(match #S(person :name "bob")
(#S(person :name name) name))
;; -> "bob"
The reason of this "patterns by default" strategy is that these readmacros (for vectors etc.) do not have quasiquotes/unquote (not even with fare-quasiquote). These literal patterns are converted to vector
, array
or structure
patterns. To match a symbol itself, use quote
such as '_
.
Rather unintentionally, the same rule applies to the quoted list (2017/11/3). So, a pattern '(a)
binds a variable a
:
(match '(1)
('(a) a))
;; -> 1
I am currently considering the removal of quoted cons from this extension, or a way to circumvent it by making quasiquote
recognize the quoted literal. (2017/11/3)
Now, elements in list constants are not treated as patterns. Use trivia.quasiquote instead. (2018/5/31)
The first argument to assoc and property patterns are evaluated in trivia, while quoted in optima.
(trivia:match '((foo . 1))
((assoc foo val) (print val))) ;; undefined variable FOO
(trivia:match '((foo . 1))
((assoc 'foo val) (print val))) ;; -> 1
(optima:match '((foo . 1))
((assoc foo val) (print val))) ;; -> 1
(optima:match '((foo . 1))
((assoc 'foo val) (print val))) ;; does not match: 'FOO versus '(QUOTE FOO) == ''foo
Assoc pattern also do not match against an improper association list while they do on Optima.
Optima skips some contents that are not cons cells, while Trivia strictly follows the behavior as defined by ANSI spec, as it just calls the assoc
function.
(trivia:match '(2 (:foo . 1))
((assoc :foo val) (print val))) ;; -> NIL, do not match
(optima:match '(2 (:foo . 1))
((assoc :foo val) (print val))) ;; -> ignores 2 and matches against (:foo . 1)
See also: Assoc, Property, Alist, Plist Pattern
This is only briefly introduced in the REAMDE of Optima. They come from fare-matcher. Since it introduces additional complexity (infix operators!) we are currently not supporting them.
See here.
Our interpretation of Trivia's compatibility to Optima can be summarized in the title. "If there is a test case in Optima, it defines the behavior of Trivia". The contents in this page are only those materials that do not follow this policy: The features which are tested in Optima but the corresponding tests are changed/removed in Trivia.
Notice that this compatibility criterion implies that the features not appearing in the unit tests of Optima do not have to be implemented in trivia, even though they are in Optima's README. The reasoning behind this policy is as follows: Since it is not tested, there is no guarantee that the feature still work in the current or the future version of Optima. These "missing" features are not counted as incompatibility.
Still, it does not mean the feature is never implemented in Trivia: It is optional to us. For example, as discussed in #51, otherwise
patterns (equivalent to _ pattern) are not tested in Optima (thus the actual behavior of this feature in Optima is undefined) but we implemented it as a result of request from @dfmorrison, which is a good thing because we add test cases and they can be backported to Optima.
For a quickstart, go to the Basics section. Below is for the people already familiar with Optima.