4 ms·
Of course since Clojure is built upon abstractions, and because it's simple to introduce your own protocols and extend them to existing types w/o conflicts - it
by swannodette 16y ago
Of course since Clojure is built upon abstractions, and because it's simple to introduce your own protocols and extend them to existing types w/o conflicts - it's straightforward to reintroduce the concept of a "pair" where the right-hand side is not a sequence. I recently encountered this challenge working on a Clojure port of miniKanren (the relational programming system described in the The Reasoned Schemer).
In miniKanren the concept of a "pair" is useful because the right hand side of a sequence in miniKanren might be a logic variable and not a sequence.
What's lovely is how simple this is. I can define a custom iteration protocol (LogicSeq) which define two functions - lfirst, lnext. Then I create a custom sequence type that returns a legitimate Sequence or logic variable for lnext.
To bring all the other collections into this protocols is 4 lines of code:
(extend-protocol LConsSeq
clojure.lang.IPersistentCollection
(lfirst [this] (clojure.core/first this))
(lnext [this] (clojure.core/next this)))
Voila! Custom iteration!
What's even more amazing is that there's hardly a perf hit. The JVM sees it's just a pass through call for real Clojure collections.
Fun stuff :)