Thanks - useful idioms to know about!
On Friday, 18 July 2014 16:18:33 UTC+9:30, puzzler wrote:
>
> Yeah, you've answered your own question. In practice, I doubt the
> difference is measurable.
>
> Another common idiom you see in Clojure code is:
> (defn f [xs]
> (if-let [s (seq xs)]
> ...
Yeah, you've answered your own question. In practice, I doubt the
difference is measurable.
Another common idiom you see in Clojure code is:
(defn f [xs]
(if-let [s (seq xs)]
...do something with (first s) and (f (rest s))...
...base case...))
This ensures that you seq-ify the input (r
I *think* I've found the answer to my own question...
In this post...
https://groups.google.com/forum/#!topic/clojure/Cuk_bJrIq-Y
I found this link (I changed the line number)...
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L2589
And if the implementat
Thanks again - that all makes sense.
One (hopefully) tiny question... an efficiency one... (and feel free not to
answer it if I've already taken up enough of your time)
If you do that and are careful, the performance of next/nil? is slightly
> better than rest/empty?.
>
If I use the next/nil?
On Thu, Jul 17, 2014 at 7:54 PM, Mark P wrote:
>
> I notice in your lazy version (below), you preface the last cons with a
> lazy-seq call, but do not do the same with the other cons calls (within the
> first recur form). I know it was only the last line that previously had a
> conj call and so
One other question occurs to me re your comment...
It's worth understanding how to go back and forth between accumulator-style
> and a lazy construction. You can convert the above non-lazy accumulator
> version into a similar version that is lazy but has no risk of stack
> overflow in the real
Woopse, typo towards the end of my last post...
Maybe the thing to do would be to use (next x) here for this
> implementation, which is angling to be lazy... But in your earlier
> acc-based my-flatten, to use (next x) instead
>
Should be... Maybe the thing to do would be to use (rest x) ...
Coming back to your helpful comments about relationship between acc-style
and lazy...
It's worth understanding how to go back and forth between accumulator-style
> and a lazy construction. You can convert the above non-lazy accumulator
> version into a similar version that is lazy but has no r
> http://clojure.org/reducers
i dare say the "When to use" part should not be at the bottom but come
right after the otherwise laughably specious "yielding code that will
get faster automatically as machines get more cores".
--
You received this message because you are subscribed to the Google
G
Slightly off-topic from original poster's question, but if you're interested in
another implementation of flatten, I suggest you take a look at the reducers
library. clojure.core/flatten is elegant but a bit slow. The reducers version
is very fast as part of a reduce/fold operation. The whol
Right. Overall lessons:
In recursion, the call stack automatically keeps track of what still needs
to be done.
In Clojure, due to Java, the stack is significantly more limited than heap,
so this can be a real limitation.
To break free of that limitation, you must somehow keep track of what still
Interesting - thank you!
Good to know about "into" as a way to achieve a non-lazy concat - in
conjunction with a vector.
I like your accumulator version - morphing the structure of the input as
you go to achieve the desired result.
I've come up with another version, that passes through both a
It's worth understanding how to go back and forth between accumulator-style
and a lazy construction. You can convert the above non-lazy accumulator
version into a similar version that is lazy but has no risk of stack
overflow in the realization of that lazy flattened list:
(defn my-flatten
[xs]
To avoid the doall-concat, you'd just have the base case return [] (btw,
you don't need the apostrophe for vectors or for the empty list), and use
`into` rather than `concat`.
If you're looking for something that exploits the structure of flatten and
uses an accumulator, you could do this:
(defn
Thanks for explaining how one creates a trampolined version from the cps
version! This makes sense.
Thanks also for alerting me to potential issues with the concat laziness.
From a code efficiency point of view, producing a lazy something and then
immediately evaluating it is inefficient. It
I haven't really used CPS myself, but I think you should be able to use the
trampoline function to clean up your code.
http://clojuredocs.org/clojure_core/clojure.core/trampoline
Jonathan
On 15 July 2014 09:13, Mark P wrote:
> I'm very new to continuation passing style (CPS), and as part of t
Yes, here's the trampolined version which won't stack overflow:
(defn my-flatten
[xs]
(letfn [(my-flatten-cps [xs k]
(if (nil? xs)
(k '())
(let [x (first xs), ys (next xs)]
(if (sequential? x)
(recur ys (fn [v] (fn [] (m
I'm very new to continuation passing style (CPS), and as part of the
learning process I've done a CPS version of a "flatten" function. Ie, it
does the same thing as the standard clojure "flatten", but is implemented
using a recursive local CPS helper function. I'm interested in comments /
cri
18 matches
Mail list logo