From the source code:
clojure.lang.Cons
(strict list item, clojure.lang.PersistentList
very similar), https://github.com/clojure/clojure/blob/1.2.0/src/jvm/clojure/lang/Cons.java#L34
public Object first(){ return _first; }
clojure.lang.LazySeq
(lazy element of the sequence), https://github.com/clojure/clojure/blob/1.2.0/src/jvm/clojure/lang/LazySeq.java#L77
public Object first(){ seq(); if(s == null) return null; return s.first(); }
Where
final synchronized Object sval(){ if(fn != null) { try { sv = fn.invoke(); fn = null; } catch(Exception e) { throw new RuntimeException(e); } } if(sv != null) return sv; return s; } final synchronized public ISeq seq(){ sval(); if(sv != null) { Object ls = sv; sv = null; while(ls instanceof LazySeq) { ls = ((LazySeq)ls).sval(); } s = RT.seq(ls); } return s; }
So, you definitely pay the price. It depends on each particular use case, how much this price affects you and whether it depends on memory savings and the lack of wasted calculations that a lazy estimate buys you.
source share