4 ms·
> They broke the abstraction layers, mess up logic with implementation your opinion is one i haven't seen before, do you care to elaborate?
by dustingetz 14y ago
> They broke the abstraction layers, mess up logic with implementation
your opinion is one i haven't seen before, do you care to elaborate?
- dschiptsov 14y agohttp://news.ycombinator.com/item?id=4517540 http://news.ycombinator.com/item?id=4517540
- zcam 14y agoApple & oranges. The only thing these 2 have in common is their name, the clojure version does a lot more. A definition of a similar keep fn in clojure would be almost indistinguishable from your lisp example (it would just be more readable).
- dschiptsov 14y agoWho told you that more is better? Why we should have nested lets and all that boilerplate for a classic filter?
- simonb 14y agoBecause you then don't need the complexity (& boilerplate) of SERIES or LOOP the moment you want to do a series of transformations on a slightly bigger list.
- jimbokun 14y agoYour three line version is pretty much equivalent to this part of the Clojure version: (let [x (f (first s))] (if (nil? x) (keep f (rest s)) (cons x (keep f (rest s))))) The rest of it appears to be performance optimizations, that probably make sense for a key function in the core library likely to be commonly invoked.
- dschiptsov 14y agoThere are some subtle differences, which makes the whole sense. Classic version has a self-evident clarity and familiar shape of a recursive function, which utilizes TCO. Perfection is achieved when there is nothing more to cut off, not when there is nothing more to pile up.)
- Evbn 14y agoNothing more to cut off, including runtime and memory usage.
- rapala 14y agoSo the classic version works in a lazy fashion, for example with infinite structures? Keep in mind that Clojure is a strict language by default.
- spacemanaki 14y agoIs the classic one actually going to be able to leverage tail-call elimination? Obviously it could be refactored to make a tail-recursive call, but correct me if I'm wrong, it wouldn't be automatic. After refactoring it, the tail-recursive version would be a bit harder to read than the naive implementation. In a sense the Clojure code is in the same boat, it's just that the optimizations are more complicated, because it's not working with singly linked lists in the "address register" and "decrement register".
- kenko 14y agoYou could write the clojure version in the exact same way (well, you wouldn't say null?, but, basically the same) as the lisp one. But it wouldn't be as efficient given the various ways sequences might be implemented in Clojure. That makes sense as part of the standard library, IMO---users of keep don't need to care about whether their sequence is chunked or whatever. And it makes sense that there should be a variety of implementers of sequences: there's more to life than singly-linked lists. (Even Guy Steele, who should know, recommended a couple years ago that language designers omit cons from their langauges!)
- lukev 14y agoThe implementation of Clojure itself is not idiomatic nor is it intended it to be so. Most of the complexity in that example, for instance, is to deal with chunked lazy sequences. In user-land code, chunking of lazy sequences is pretty much a pure performance optimization that you don't have to worry about. Granted, it's not a ideologue "turtles all the way down" LISP. But it isn't intended to be. If you want that, I advise you to find an old Lisp Machine and use that.