tc39 / proposal-upsert

ECMAScript Proposal, specs, and reference implementation for Map.prototype.upsert
https://tc39.es/proposal-upsert/
MIT License
202 stars 14 forks source link

`myMap.has(key) ? myMap.get(key) : none` #48

Closed conartist6 closed 2 years ago

conartist6 commented 2 years ago

The most common problem in Map usage is the one this proposal doesn't address. myMap.has(key) ? myMap.get(key) : none still isn't sufficiently safe or static. Class extension can break it. Typescript can't handle it. Flow can't handle it

What if the API was simply:

myMap.getOr(key, defaultValue);

Then upsert becomes:

myMap.set(myMap.getOr(key, 0), value + 1);

myMap.set(key, myMap.getOr(key, 0) + 1);
gibson042 commented 2 years ago

myMap.set(myMap.getOr(key, 0), value + 1) only implements upsert if getOr(key, defaultValue) returns key, which seems rather pointless.

But regardless, note that the README identifies distinct scenarios and that each of them potentially mutate the map:

Getting a possibly-default value without mutating the map would be an expansion of scope, albeit potentially an appropriate one. But not at the expense of the above scenarios in either behavior or comprehensibility (probably ruling out something like const value = map.emplace(key, { skipInsert: ()=>defaultValue }) unless the priority of insert vs. skipInsert can be made obvious).

conartist6 commented 2 years ago

My apologies, I combined a two line example into one line at the last moment and i messed it up. It should have been:

myMap.set(key, myMap.getOr(key, 0) + 1);
papb commented 2 years ago

I'd also love to see .getOr. I'm convinced it does not replace the current proposal though. Is there another open proposal for it, by any chance?

conartist6 commented 2 years ago

I've reopened this because I think it could still be viable. See: https://es.discourse.group/t/symbol-lazy/1534

conartist6 commented 2 years ago

oops this wasn't the issue I thought it was