Fork me on GitHub

I do like the composition in the grid definition from @amacdougall. On the other hand, it takes the approach of, “make this in a sequence, and then convert the sequences to vectors”. That’s a great approach, but I also wonder about doing it directly:

(defn grid [width height]
  (mapv (fn [y]
          (mapv (fn [x] (create-cell x y)) (range width)))
    (range height)))
Of course, under the covers mapv is just (into [] (map …)), so there’s no actual benefit here. It just “feels” like fewer steps to me 🙂


Just to "well, actually" you 🙂 mapv is a bit more optimized when dealing with a single collection:

([f coll]
     (-> (reduce (fn [v o] (conj! v (f o))) (transient []) coll)


@quoll: the double mapv is what I started with, but the syntax just looked clumsy. I may end up doing that anyway if I really run into some kind of performance issues, but I don't expect any of my grids to be larger than 100 x 100 in practice. 10k cells is peanuts.


@slipset: I’m not sure what you’re getting at here. The calls to create-cell are done lazily as the calls to mapv do their work, and each mapv is making a single vector (which is required in the final output), each one of which gets populated as a transient


@amacdougall: I agree that it looks clumsy. The single for seemed more elegant… but having to massage it into vectors seemed clumsy as well. I figured I’d present the alternative, though I should have been clearer in stating that I don’t believe it’s better in any way.


your original use of for feeding into partition means that the create-cell calls are all primed to be called lazily. Running that into (mapv (partial into [])) means that it ends up with the same number of transient construct/populate calls.


The code I posted was part of the mapv implementation, which shows that for a single collection, mapv is probably more performing than (into []...


Indeed… now that I think about it, since my nested mapv/mapv ends up with the same number of transient/into[]/persistent! calls as the original grid (from @amacdougall) and the fact that code is operating at a higher level of composition… I withdraw the suggestion of a nested mapv. It does the same thing, but it’s at a lower conceptual level.


@slipset: have a look at the source for into. It does the same thing


Yes, but only if to implements IEditableCollection which I assumed [] did not?


But I’m running into cloelessness here...


=> (instance? clojure.lang.IEditableCollection [])


I stand corrected 🙂


Cool, I read IEditableCollection as ‘a collection that is editable’, but the definition,, just specifies that the collection need to have a asTransient function