A different semantics for WeakMap#get default value

Herby Vojčík herby at mailbox.sk
Tue Jan 17 11:10:43 PST 2012

Allen Wirfs-Brock wrote:
> On Jan 17, 2012, at 3:45 AM, Herby Vojčík wrote:
>> Brendan Eich wrote:
>>> Clearly(!) a set-if-not-present method should not be misnamed
>>> "get".
>>> I like the optional sentinel-meaning-not-found for get, and
>>> setDefault per Python as Tab pointed out. Agree they should not
>>> be merged into one API. Bikeshedding setDefault at leisure (in
>>> background in my head ;-).
>> Like: getIfAbsentSet(key, dflt) with dflt being mandatory? Still
>> there is question of laziness of dflt, the original
>> #get:ifAbsentPut: has the block as its second argument.
> The Smalltalk solution to this problem is the at: key ifAbsent:
> block method.

There is also
   at: key ifAbsentPut: block
At least in Squeak it was there.

> This subsumes both get with default value and get create if missing
> use cases plus others.  In JS we might say:
> col.getIfAbsent(key) {|| 42};  //use 42 if no present
> col.getIfAbsent(key) {|| col.defaultValue};  //have collection
> provide the default value
> col.getIfAbsent(key) {|| col.put(key, 42); 42}  //if key isn't there
>  add it with an appropriate vaue

except it computes collection twice. If it is something like:

   foo.bar().getIfAbsent(key) {|| foo.bar().put(key, 42); 42}

it is a bit clumsy. You can pass the collection itself in an argument

   foo.bar().getIfAbsent(key) {|c| c.put(key, 42); 42}

but you have the same problem with value, if it is computed, you must

   foo.bar().getIfAbsent(key) {|c| let v = baz(); c.put(key, v); v}

so it seems better to have different api and write

   foo.bar().getIfAbsentSet(key) {|| baz()}

Also, Mark S. Miller wrote:

> As it is now, I can give someone a read-only view of a WeakMap wm my
> simply giving them

> { get: wm.get.bind(wm), has: wm.has.bind(wm) }

so distinct API is for writeback version is probably not a bad idea.

> Allen


More information about the es-discuss mailing list