In https://github.com/clojure/core.logic/wiki/Differences-from-The-Reasoned-Schemer the pair? predicate is defined, but this will make the following true
(pair? '(a b c)) ;-> true
(pair? (lcons '(1 2) \s)) ;-> true
Isn't a pair (a . b) or (a b), not a list of more than 2 items?no
in traditional lisps, lists are exposed linked lists of cells, each cell is like a 2 element array, one of the elements is called the car and one is called the cdr. those cells are what are pairs, that pair? returns true on in scheme
so (a . b) is a pair with the car a and the cdr b. (a b) is a pair where the car is a, and the cdr is (b), and (b) is a pair where the car is b and the cdr is nil
(a b c) is the same as the (a b) case extended by another level
https://people.csail.mit.edu/jaffer/r5rs_8.html#IDX319 is some documentation on the scheme function
Ah yes, I know about that. It's a cell, right?
yes, and that all applies to scheme, clojure is different, clojure is primarily concerned with seqs (clojure lists are seqs) which don't actually expose the cells that make them up
but having cons cells and improper lists (cells where the cdr is not a pair or nil) is useful in minikanren because you can represent a list where you haven't figured out what the rest of the list yet (the cdr is a logic var)
so core.logic has lcons to provide for that
I understand, but that makes pair a little odd in Clojure.
it is
pair doesn't really exist in the wider world of clojure, but exists in core.logic because The Reasoned Schemer is an important source of documentation for it, and examples in TRS need it
Yeah when I had a go at implementing microkanren, I found probably half the code of the complete implementation was just implementing scheme like linked lists in clojure.
well, really you'd need something like it even without the TRS to reason about lists, but the reason it is the way it is is because of TRS
Thanks