what's the correct way to ask whether a given object obeys the sequence protocol? I.e. can I call first/rest on it? seq fails on nil and seq? returns false on [1]
the documentation for sequential? tells me something obtuse.
clojure.core/sequential?
[coll]
Added in 1.0
Returns true if coll implements Sequential
clojure.core/sequential? is defined in clojure/core.clj.`(source seqable?)
(defn seqable?
"Return true if the seq function is supported for x"
{:added "1.9"}
[x] (clojure.lang.RT/canSeq x))sequential i think is a specific clojure marker that a class can have. But itβs not as general as what you want i think
(let [h (doto (java.util.HashMap.) (.put "first" 1))]
[(sequential? h) (seqable? h)])
[false true]but this can quickly get into βis this a seq, or can this be a seqβ. You may or may not care about the difference
I want to write a function which traverse two objects in parallel concentrically with first/rest. And I want to ask whether they support first/rest.
you might care then.
(let [h (java.util.HashMap.)
_ (doseq [x (range 20)]
(.put h x x))
h' (zipmap (range 20) (range 20))]
[(second h) (second h')])
[#object[java.util.HashMap$Node "0x4167172b" "1=1"] [7 7]]these two maps will (= h h') as true
There are no inputs for which first/`rest` would work and seqable? would return false, and vice versa.
The equality of Java and Clojure collections that also have different semantics and even different hash codes is a point of contention. :) There's a ticket for the latter, not sure about the former.
And the case demonstrated by Dan above is not really about Java colls at all:
(let [vals (interleave (range 10) (range 10))
hm (apply hash-map vals)
sm (apply sorted-map vals)]
[(= hm sm)
(= (seq hm) (seq sm))])
=> [true false]I've updated my laptop to a different architecture, and some things are not yet working as I expect.
I'm having a bit of different behavior from the clj command line vs cider.
Can someone tell me whether this is normal?
(defn alpha-< [a b]
(println [:a a :b b])
(cond (= a b)
false
(and (empty? a) (seqable? b))
true
(and (seqable? a) (empty? b))
false
(not= (first a) (first b))
(neg? (compare a b))
:else
(alpha-< (rest a) (rest b))))
(alpha-< '(a) '(b a))
This gives a somewhat useful error using clj at command line
user=> (alpha-< '(a) '(b a))
(alpha-< '(a) '(b a))
[:a (a) :b (b a)]
Execution error (ClassCastException) at user/alpha-< (REPL:13).
class clojure.lang.PersistentList cannot be cast to class java.lang.Comparable (clojure.lang.PersistentList is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
user=>
but in cider, it just saysThat has always been the case, persistentlist has never implemented comparable which is required for compare
ok, but in cider it doesn't tell me what kind of cast is attempted.
just that there's a problem casting
the jvm will sometimes emit stacktrace information for certain exceptions, there is a flag you pass to turn that (dumb) behavior off
do you mean OmitStackTraceInFastThrow ?
yes