Fork me on GitHub
michele mendel18:01:19

In 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?


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

michele mendel19:01:25

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

michele mendel19:01:38

I understand, but that makes pair a little odd in Clojure.


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.

Ben Sless10:12:59

I saw another approach at Another approach could also be something which implements iseq then you cons on it, no?


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