On Wed, Jan 14, 2009 at 4:03 PM, Jason Wolfe <jawo...@berkeley.edu> wrote:
>
> To keep this manageable, I'll cut out the parts where I don't think
> comments are needed.

Good idea!

>> > (defn concat-elts "Lazily concatenate elements of a seq of seqs." [s]
>> >  (when (seq s) (lazy-cat (first s) (concat-elts (rest s)))))
>>
>> > (defn lazy-mapcat "Like mapcat but is lazy like map" [f s]
>> >  (concat-elts (map f s)))
>
> Yes.  I would be happy to drop concat-elts and lazy-mapcat, if the
> built-in concat (which seems to be used by mapcat) was changed to be
> less eager (in the apply sense just mentioned above).
>
> user> (take 0 (apply concat (report-seq "" [[1] [2] [3] [4] [5]])))
> (first  [1] )
> (rest after  [1] )
> (first  [2] )
> (rest after  [2] )
> (first  [3] )
> (rest after  [3] )
> nil
>
> This can end up being a real drag in situations like (apply concat
> (map #(recurive-call ...) ...)), since it may result in an exponential
> amount of extra work being done.  Any chance of this being changed?
> (It should be possible to get rid of the last 4 evaluations here,
> without getting into the territory of our last conversation about
> laziness :))

I don't see why the built-in concat couldn't be defined like yours.

>> > (defn chunk "Lazily break s into chunks of length n (or less, for the
>> > final chunk)."
>> >  [n s]
>> >  (when (seq s)
>> >    (lazy-cons (take n s)
>> >               (chunk n (drop n s)))))
>>
>> This is so close to 'partition', that I think I'd prefer there be only
>> one, or at least have related names.
>
> OK, I agree the name should be closer to partition (which I'd
> forgotten about), but I think this one is at least as useful as
> partition  (You can recover partition from this one by (take-when #(=
> (count %) n) (chunk n s))) but not vice-versa.)   Any suggestions on a
> name?

Perhaps 'partition-all' ?
I'd vote to have this in contrib.

>> (defn my-mevery? [f & seqs]
>>   (every? identity (apply map f seqs)))
>
> Yes, I believe so ... that's a much nicer way of writing it.
>
>> Someone suggested all the functions that currently take a predicate
>> and one seq ought to take multiple seqs and work like 'map'.  I
>> suppose this would include: every? any? some etc.  Seems pretty
>> convenient, and I've not heard arguments against it.  But without
>> that, I think I'd rather use 'identity' and 'apply map' than have an
>> m-version of all the seq functions.
>
> Yes, I would of course prefer that the built-in versions take multiple
> seqs and work like map.
> If not, I guess I agree with you that it's better not to create m-
> versions of everything.

These could be changed to act like 'my-mevery?' above.  Is this a
complete list?  -->  every? not-every? some not-any?

I believe functions that return the values from the input seq are NOT
candidates for this?  That includes:
filter remove take-while drop-while split-with

Instead the first three might suggest corollaries:
map-when map-when-not map-while

>> I think I'd rather this be a feature of the map itself, rather than
>> depend on each 'get' to be a 'safe-get'.  Perhaps if 'get' finds
>> nothing and no default value is given, it could check the map's
>> metadata for a :default-value or :throw-unless-found item.
>
> I think I'd be equally happy with "safe maps" as you suggest as using
> safe-get.  But, one or the other is definitely useful ... I've been
> bitten several times by misspelled keys, which can create difficult-to-
> find bugs.

I know people have asked previously for maps that know their own
default value.  I suppose the metadata could be supplied directly:

#^{:default "not found"} (hash-map :a 1, :b 2)

That's a bit ugly, but you could use it on {} literals.  Otherwise I
guess you'd need extra constructors.

(hash-map-default "not found" :a 1, :b 2)
(sorted-map-throw :a 1, :b 2)
(safe-array-map :a 1, :b 2)

Hm.  Is it worth it?  Any naming ideas?

>> > (defn merge-agree "Like merge but returns nil if there are
>> > inconsistent key/value pairs."
>> >  ([] {})
>> >  ([map] map)
>> >  ([m1 m2 & maps]
>> >     (when (every? (fn [[k v]] (= v (get m1 k v))) m2)
>> >       (apply merge-agree (merge m1 m2) maps))))
>>
>> Maybe if it accepted the = function as a arg (like merge-with) it
>> would be a little more general?
>
> Well, then which value would you use (if two values are my-equal but
> not =)?

Oh.  Good point.  I guess I was thinking it would be like
'merge-with', but if the conflict resolution function returned nil or
false, you'd get back a nil instead of a map.

> With merge-with, I think I would have to say
> (apply merge-with + accounts (map (fn [[k v]] (hash-map k v)) (concat
> deposits withdrawls)))
>
> which is considerably uglier and less clear IMO.  Any chance of
> changing merge-with in this way?

Yes, it would just require replacing a use of 'key' and 'value' with
'first' and 'second' in the definition of 'merge-with'.  I can't think
of a good reason not to do this.

--Chouser

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to