On Wed, Jan 14, 2009 at 4:03 PM, Jason Wolfe <[email protected]> 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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---