For laziness analysis, I typically use code like this:

(defn trace-seq* [name xs]
  (for [x xs]
    (do (println (str name ": " x))
        x)))

(defmacro trace-seq [xs]
  `(trace-seq* ~(str xs) ~xs))

If I use it on the code I posted, I get this:

user> (take 3 (scan-filter-zip even? (trace-seq (iterate inc 0))
(trace-seq (range 10))))
((range 10): 0
(range 10): 1
(range 10): 2
(range 10): 3
(range 10): 4
(range 10): 5
(range 10): 6
(range 10): 7
(range 10): 8
(range 10): 9
(iterate inc 0): 0
[0 0] (iterate inc 0): 1
[1] [1 2])

You might want to temporarily redirect *out* so you don't get
interleaved return values and traces.

So you can see that scan-filter-zip is lazy in the source sequence but
apparently not the primary input sequence. That was surprising to me
because I see nothing in my code that should have forced that. Then I
remember that some functions like range are not really lazy but only
chunky-lazy. You can verify this by replacing (range 10) by (range
100) and noting that the trace stops at the 32nd element (chunks are
currently 32 elements wide). So, everything is as lazy as can be,
given the input sequences.

-Per

On Wed, Mar 24, 2010 at 1:35 AM, Douglas Philips <d...@mac.com> wrote:
> On 2010 Mar 23, at 9:14 AM, Per Vognsen wrote:
>
>> Remember the one-liner I gave you last time?
>
> Yup. It was the 'hard coded + 0' parts that had been ruminating in the back
> of my mind as being something that could be abstracted out. :)
>
> Since the one you just posted didn't have all the features of my version,
> I've taken the liberty of
> adjusting it:
> ; Variation on Per Vognsen's version.
> (defn semi-map
>  [pred fun seq1 seq2]
>  "Lazy sequence of seq1 optionally combined with seq2.
>   when pred on seq1 item is true, yield fun of seq1 and seq2
>   otherwise yield seq1 item without advancing seq2.
>   Example: (semi-map vowel? vector \"Hello Word\" (iterate inc 1))
>   -> (\\H [\\e 1] \\l \\l [\\o 2] \\space \\W [\\o 3] \\r \\d)
>  "
>  (map #(if (pred %1) (fun %1 (first %2)) %1)
>       seq1
>       (reductions #(if (pred %2) (rest %1) %1)
>                   seq2 seq1)))
> ;;;
>
> What I don't understand (yet) is how to do a lazyness analysis on this
> similar to what
> Meikel Brandmeyer did with my original code.
>
> So, for my own understanding:
>    the outermost map is lazy, hence nothing will happen it the first result
> needs to be realized.
> OK, so far so good.
>    when the first result of the map needs to be realized, I'm getting a bit
> foggy...
>    the 2nd parameter to map 'seq1' will have to have its first element (and
> tail?) realized
>        in order to call the mapping function #(if...)
>    the 3rd parameter to map '(reductions...)' will have to have its first
> element realized
>        in order to call the mapping function #(if...) of the outermost map.
> then:
>    In order to realize the first value of the result of reductions, both the
> first value of seq1
>       has to be realized to pass in as the second parameter to the
> reductions' function #(if ...)
>
> Ok, so now my head hurts. But in a good way.
>
> I think I have convinced myself that the only "eager" realization/evaluation
> might be of the tail of seq1, but I'm not sure.
>
> Thanks Per!
>
> -Doug
>
> --
> 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
> Note that posts from new members are moderated - please be patient with your
> first post.
> 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
>
> To unsubscribe from this group, send email to
> clojure+unsubscribegooglegroups.com or reply to this email with the words
> "REMOVE ME" as the subject.
>

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
"REMOVE ME" as the subject.

Reply via email to