ISeq
is an interface for seqs, so LazySeq
implements ISeq
as well. The seq
function type hints its return as an ISeq
.
Calling seq
on a vector will return a PersistentVector$ChunkedSeq
, which is a different kind of lazy sequence. It's realization is chunked to amortize the cost of producing it element-by-element (I think it evaluates 8 elements at a time iirc).
If you really want a LazySeq
specifically, you could do
(lazy-cat [1 2 3])
but that would only be useful to force element-by-element evaluation and eliminate the chunking behavior.
In Java, this would be:
// once
Var lazyCat = RT.var("clojure.core", "lazy-cat");
// at use
IPersistentVector vector = ...
ISeq lv = (ISeq) lazyCat.invoke(vector);
Note that it would give me the tinglies to actually cast the result to LazySeq
so I used the interface ISeq
anyways here. There is no guarantee that the concrete class LazySeq
is what you'll actually receive at any point in the future. Given that, you're just as well off calling seq directly:
// once
Var seq = RT.var("clojure.core", "seq");
// at use
IPersistentVector vector = ...
ISeq lv = (ISeq) seq.invoke(vector);
In general, it is a good idea to always invoke Clojure classes through Vars obtained from the runtime and to only cast to interfaces, never to concrete types. That greatly reduces the chances that things will break for you from release to release.