Mark, I thought your blog post was really, really good. I have forwarded it to a lot of people; I hope you don't mind!
As far as caching goes: I think, regardless of the theoretical considerations of = that caching a lot of objects is ridiculous from a performance perspective. Access to ram takes a long, long time from the CPU's perspective and on-chip caches are never that big. In a world with lots of processing power and not that much bandwidth (not to mention the overhead of garbage collection and various other things) I never cache anything until I know it will provide a distinct benefit. I have to break newer programmers of that habit all the time (I work currently on 3d graphics on NVIDIA's Tegra platform). Furthermore, moving to Andriod platforms means you are dealing with a platform that is always going to be bandwidth and resource constrained as far as ram goes. The tradeoffs here are harder to make and require more research, but generally trying to compute things instead of store them will get you a lot farther especially with regards to the anemic on-chip cache that most ARM processors have. So clearly, for my applications I will be using the stream abstraction unless I have a reason to use the truly lazy (I wouldn't consider a non-caching approach truly lazy) approach. I am not criticizing the decision to be correct first and performant later, but I think that streams fit what I do much better than lazy seqs. I agree with Mark's assessment that the vast majority of the sequences in his program are either only used once or so cheap to create that caching is pointless. This matches my world that has an update-render loop where a lot of the information just doesn't matter after the rendering engine gets to it. Chris On Jan 8, 8:09 am, Matt Revelle <mreve...@gmail.com> wrote: > On Jan 8, 2009, at 8:55 AM, Rich Hickey <richhic...@gmail.com> wrote: > > > > > > > On Jan 8, 7:26 am, Konrad Hinsen <konrad.hin...@laposte.net> wrote: > >> On 08.01.2009, at 11:22, Mark Engelberg wrote: > > >>> So my blog post has a dual purpose. First, I explain the "gotcha" > >>> that Stuart and I discussed. Second, I report back to the community > >>> about the actual experience I had in the past month, exploring > >>> laziness in Clojure. I decided to blog it rather than post it here > >>> primarily due to its length. > > >> An interesting analysis. Looking my own applications, I tend to agree > >> with your observations, but then I also have a similar code base as > >> you have: almost all of it is purely functional code using Clojure's > >> basic data structures. > > >> I also agree with your conclusion that the critical point is lazy > >> sequences whose constructors are not referentially transparent. I > >> wonder if there is any way to have them detected reliably (at compile > >> time or at run time), but I expect this can't be done. Another > >> solution would be to detect lazy sequences guaranteed to be purely > >> functional because of the exclusive use of safe functions, and make > >> them uncached by default. That should be doable but perhaps with an > >> unreasonable effort or a high runtime penalty. > > > The sequence abstraction in Clojure is the list abstraction of Lisp. > > No more, no less. It is inherently a persistent abstraction. When you > > ask for the nth element/rest, you get the identical item every time. > > All laziness adds is the fact that rest might not exist until you ask > > for it. Once you do, it's a Lisp list. It doesn't matter whether it > > originally came from an ephemeral source or a long-running calculation > > or whatever. The claim "So the amazing thing is that whether you > > choose to build a cached or uncached sequence, it makes not one bit of > > difference to the consumers of your sequence" is simply untrue. The > > promise of the abstraction is not merely that the nth item/rest will > > be equal - it is that it will be identical. I.e. a seq is persistent > > and immutable. There's nothing wrong with Lisp's list abstraction nor > > its realization as seqs in Clojure. > > > Making seqs 'non-caching' makes no sense because they are no longer > > the same abstraction. Lazy != ephemeral. Seqs and streams are > > different abstractions. > > > The questions really are, is there room for additional, ephemeral, > > abstraction - streams, and can filter/map et al be freed from working > > only with the seq abstraction. I've said yes to both of these and have > > a working solution that supports transparent interoperation of seqs > > and streams, thread safety, and single-source algorithm definition for > > both uses. It is not based on non-caching seqs. > > > I've been holding off on integrating this as it is a fairly > > substantial change (under the hood, no change at all for consumers), > > introduces a new abstraction (though no impact until you use it), and > > might delay 1.0. > > > Do people want it now? > > I'd use it now. If it's more important to get 1.0 out, I'd happily > wait until 1.1. > > > > > Rich --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---