Skip to content

Instantly share code, notes, and snippets.

@simon-brooke
Created August 8, 2025 09:21
Show Gist options
  • Save simon-brooke/9385cdb9b8e71fa0928346c090c3f4b6 to your computer and use it in GitHub Desktop.
Save simon-brooke/9385cdb9b8e71fa0928346c090c3f4b6 to your computer and use it in GitHub Desktop.
Are you lazy?
(ns are-you-lazy
"Sometimes it's useful to check whether an object is lazy without
exploring the whole of it!"
(:import [clojure.lang IPending LazilyPersistentVector LazySeq]))
(defn lazy?
"Return `true` if this `coll` lazy, else `false`.
**NOTE THAT** Probably all lazy sequences are instances of
`clojure.lang.LazySeq`, but `LazySeq` implements an interface `IPending`
which as far as I can see nothing else implements, and I'm wondering
whether the existence of this interface implies that in some future
release of Clojure, there may be lazy things which are not instances of
`LazySeq`.
**NOTE THAT** there's also a class `clojure.lang.LazilyPersistentVector`,
which does *not* implement `IPending` and does not subclass `LazySeq`.
I don't know what it's use case is; it is used internally by atoms and
by regular expression matchers but I don't know whether it is expected to
be present in clojure users (as opposed to implementors) code."
[coll]
(or
(instance? LazySeq coll)
(instance? IPending coll)))
;; Interestingly,
;; (apply or (map #(instance? % coll)
;; (list LazySeq IPending LazilyPersistentVector)))
;; does not work because `or` is a macro.
(lazy? '(1 2 3)) ;; => false
(lazy? (range)) ;; => true
(lazy? (map inc '(1 2 3))) ;; => true
;; Interestingly, calling LazilyPersistentVector/create does not create a
;; LazilyPersistentVector:
(type (clojure.lang.LazilyPersistentVector/create (range 10))) ;; => clojure.lang.PersistentVector
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment