beginners

Jim Newton 2025-05-14T13:43:49.330409Z

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]

Jim Newton 2025-05-14T13:45:03.977299Z

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.

dpsutton 2025-05-14T13:45:10.513359Z

`(source seqable?)
(defn seqable?
  "Return true if the seq function is supported for x"
  {:added "1.9"}
  [x] (clojure.lang.RT/canSeq x))

dpsutton 2025-05-14T13:45:38.640989Z

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

πŸ‘πŸ» 1
dpsutton 2025-05-14T13:46:48.759919Z

(let [h (doto (java.util.HashMap.) (.put "first" 1))]
  [(sequential? h) (seqable? h)])
[false true]

dpsutton 2025-05-14T13:47:20.260289Z

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

Jim Newton 2025-05-14T13:48:05.463879Z

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.

dpsutton 2025-05-14T13:50:56.754769Z

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]]

dpsutton 2025-05-14T13:51:48.625539Z

these two maps will (= h h') as true

p-himik 2025-05-14T13:52:33.177329Z

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.

πŸ‘πŸ» 1
p-himik 2025-05-14T13:55:28.499549Z

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]

Jim Newton 2025-05-14T14:00:43.342639Z

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 says

2025-05-14T14:42:11.026849Z

That has always been the case, persistentlist has never implemented comparable which is required for compare

Jim Newton 2025-05-14T14:58:44.428629Z

ok, but in cider it doesn't tell me what kind of cast is attempted.

Jim Newton 2025-05-14T14:58:49.973449Z

just that there's a problem casting

2025-05-14T15:44:40.176419Z

the jvm will sometimes emit stacktrace information for certain exceptions, there is a flag you pass to turn that (dumb) behavior off

daveliepmann 2025-05-14T15:47:44.218589Z

do you mean OmitStackTraceInFastThrow ?

2025-05-14T15:50:21.936429Z

yes