Tcl Source Code

View Ticket
Login
Ticket UUID: 745851
Title: [dict merge]
Type: Support Version: None
Submitter: jenglish Created on: 2003-05-30 01:15:36
Subsystem: None Assigned To: dkf
Priority: 7 High Severity:
Status: Closed Last Modified: 2009-07-29 19:41:30
Resolution: Closed By: dkf
    Closed on: 2004-03-12 23:33:00
Description:
A useful addition to [dict] would be a command that
sets multiple dictionary entries in a single step:

dict merge $dictval1 $dictval2 ? ... $dictvalN ?

which would return a copy of $dictval1, extended or
modified by the values in $dictval2.  If multiple
arguments are supplied, values in later arguments
override those in earlier ones.

That is:

proc dict_merge {dict1 args} {
     foreach dict $args {
        foreach {key value} $dict {
            dict set $dict1 $key $value
        }
     }
    return $dict1
}

(This was discussed on tcl-core, but the vote on TIP
111 was already in progress so it didn't make it into
the initial implementation.)
User Comments: dkf added on 2009-07-29 19:41:30:

IP - Comment Removed: 130.88.1.31

dkf added on 2008-12-07 18:30:38:

data_type - 210894

dkf added on 2004-03-13 06:33:00:
Logged In: YES 
user_id=79902

TIP was accepted and implemented.

Although it was an inspiration, I didn't use the submitted
patch because:
 * The implementation had problems triggerable by attempting
to merge non-dictionary values.
 * The documentation wording wasn't quite clear.
 * The test suite was too incomplete for my taste (I prefer
to test as many failure modes as possible.)

dkf added on 2004-03-02 04:24:40:
Logged In: YES 
user_id=79902

It won't make *any* performance difference except in the
case where someone hands in an unshared object, and then
(especially if the object was large) the difference is going
to be much more significant.  Many list commands (and other
dict subcommands) behave this same way; it is a common core
idiom and there are coding patterns that take advantage of
it to good effect.

Forcing a full copy is just unfriendly.

jenglish added on 2004-02-29 03:54:30:

File Added - 78372: tcl-dict-merge.patch

jenglish added on 2004-02-29 03:54:29:
Logged In: YES 
user_id=68433

Updated patch including suggestion below (though I'm not
sure if this isn't a premature optimization; it won't affect
the asymptotic runtime in normal circumstances).  Also
includes documentation and a rudimentary update to the test
suite.

dkf added on 2004-02-21 19:39:00:
Logged In: YES 
user_id=79902

Patch review: Shouldn't duplicate the first dictionary
piecemeal.  Better to insert the values into that (if
shared, use the standard Tcl_DuplicateObj idiom to unshare it).

jenglish added on 2004-02-21 08:34:16:
Logged In: YES 
user_id=68433

Just found myself wanting [dict merge] again; raising the
priority.

jenglish added on 2003-09-07 23:45:21:
Logged In: YES 
user_id=68433

Argh, does this really require a TIP?  I was under the
impression that since [dict] has not yet appeared in an
official release that the details were still fluid.

dkf added on 2003-09-07 03:16:36:
Logged In: YES 
user_id=79902

Good use case.  Just what I wanted. I'd be happy to support
a TIP.

(I'm less certain about the C interface.  Merging is a
pretty trivial thing to do with the current C API after all.)

jenglish added on 2003-09-06 08:48:49:

File Added - 60765: tcl-dict-merge.patch

Logged In: YES 
user_id=68433

(Let's see if SourceForge is working today...)

Attached patch implements [dict merge].  Documentation and
test cases still missing.

This might also be a useful thing to have in the C
interface, should refactor.

PS: for a real-live, actual use case, see  'proc myReturn'
in the EXAMPLES section of return.n (r1.7), which currently
uses:

    set options [eval [list dict create -level 1] $args]

This could be replaced with

   set options [dict merge {-level 1} $args]

jenglish added on 2003-05-31 00:42:02:
Logged In: YES 
user_id=68433

> would using C for this purpose be a significant
advantage?  
> It increases the maintenance load, after all...

So that it could be spelled [dict merge] instead of
[dict_merge] :-).  There are minor efficiency issues as
well.

But mostly, this is a useful primitive operation on
dictionaries that (I feel) should be part of the core
interface.

dkf added on 2003-05-30 15:48:44:
Logged In: YES 
user_id=79902

A better implementation might go like this:

proc dict_merge {dict1 args} {
   foreach dict $args {
      dict for {key val} $dict {
         dict set dict1 $key $val
      }
   }
   return $dict1
}

However, would using C for this purpose be a significant
advantage?  It increases the maintenance load, after all...

jenglish added on 2003-05-30 08:17:05:
Logged In: YES 
user_id=68433


[dict merge] can also be expressed as:

    [eval dict replace [list $dict1] $dict2 ... $dictN]

but I'd prefer a solution that doesn't involve [eval].

A variant form that operates on dictionary variables would
also be useful (don't know what to call it though.)

Attachments: