Just finished working on something with Alexy Khrabrov & Chouser on
IRC, and the three of us are wondering if the result might be
generally useful.
(defn assoc-in-with
"supply a default-map instead of a hash-map"
[m default-map [k & ks] v]
(if ks
(assoc m k (assoc-in-as (get m k default-map) default-map ks v))
(assoc m k v)))
Also, is there room for a sister fn update-in-with?
Thoughts?
Sean
As I mentioned in IRC, this could actually be a 4-argument
version of 'assoc-in' instead of a new function. Assuming of
course Rich likes the idea.
--Chouser
http://joyofclojure.com/
Where would the default go? Also, need it be a map, vs anything
associative (e.g. a vector)?
Rich
user=> (assoc [] 1 :a)
#<CompilerException java.lang.IndexOutOfBoundsException>
So I say this should be map only. Granted, assoc-in already has this
issue.
Also, what do you mean by your question "Where would the default go"?
I don't understand what you're getting at yet.
Sean
On Jan 29, 8:44 am, Rich Hickey <richhic...@gmail.com> wrote:
> On Fri, Jan 22, 2010 at 8:57 AM, Chouser <chou...@gmail.com> wrote:
Since update-in could use this pattern as well, I don't think the
default should go after the value (or update fn) position.
I think where Sean put it is fine -- after the collection, before
the vector of keys.
I don't see why it needs to be restricted to a map -- all the
normal assoc rules apply.
--Chouser
http://joyofclojure.com/
As soon as you are varidic with update-in I think you'll need new
names, i.e. can't just add another arity to assoc-in and update-in.
> I don't see why it needs to be restricted to a map -- all the
> normal assoc rules apply.
>
Right.
I wonder though, if a single default coll is sufficient. There are
potentially multiple levels to the structure, using different data
structures at each level.
Rich
But this does:
user=> (assoc [] 0 :a)
[:a]
> So I say this should be map only.
I don't think so.
> Also, what do you mean by your question "Where would the default go"?
> I don't understand what you're getting at yet.
>
Just a question of arg order.
Rich
My last concern with assoc-in & arrays has to do with how it is
currently used for maps. The way it creates elegant nested structures
is nice, and it requires very little understanding of the current
structure of the map.
However, assoc-in has a few more constraints when dealing w/ arrays,
and the end user does have to keep track of array structure. Granted
they have to do this anyway by the nature of arrays. I personally
always use conj when creating a vector of vectors, so I don't se much
of a use case (Hmmm... Sparse Matrix? That's better as a map...).
I DO see a great use case for update-in-with working on vectors, so
maybe assoc-in-with working on vectors should be implemented simply
for symmetry.
I dunno. That's all I've got right now.
On Feb 3, 11:03 am, Rich Hickey <richhic...@gmail.com> wrote:
(defn assoc-in-maybe-creating [coll keys creator-fns value] ...)
so it can be used:
(assoc-in-maybe-creating
[ {:a (sorted-map :X 1, :Y 2, :Z 3)
:c (sorted-map :X 1, :Z 3)}
{:b (sorted-map :X 1, :Y 2, :Z 3)}
{:f (sorted-map :X 1, :Y 2)}]
[0 :b :X]
[vector hashmap sorted-map]
1)
returning
[ {:a (sorted-map :X 1, :Y 2, :Z 3)
:b (sorted-map :X 1)
:c (sorted-map :X 1, :Z 3)}
{:b (sorted-map :X 1, :Y 2, :Z 3)}
{:f (sorted-map :X 1, :Y 2)}]
or like that
(assoc-in-maybe-creating
[]
[0 :a :Y]
[vector hashmap (fn []
(struct-map CustomStruct
:required-field1 value1 :required-field2 value2))]
2)
Name is temporary, I couldn't think of better one.