(Map|Set|WeakMap)#set() returns `this` ?

Jussi Kalliokoski jussi.kalliokoski at gmail.com
Wed Dec 5 01:50:59 PST 2012

My 2 cents against the windmills...

I personally think returning `this` in absence of any meaningful value (and
chaining in general) is a bad pattern. Chaining leads to worse readability
(there's nothing subjective about this, if you have to scan the code to
another page to figure out which object the code is interacting with, it's
bad readability) and returning this is more future-hostile than returning
nothing. If we in the future come up with something actually useful the
function could return, there's no turning back if it already returns
`this`. For set(), meaningful values include the value that was set, a
boolean whether the value was added or replaced, etc., whereas `this` is
meaningless since you have it already. Returning `this` in absence of
meaningful values is also a mental overhead: "Does this return a meaningful
value, or just this, so can I chain it?"

I, like Andrea, have dreamed that Array#push() returned the value I passed
to it (although the reason that it doesn't is probably that you can pass
multiple values to push), I have a lot of cases where I've hoped that I
could do this:

return objects.push({
  foo: bar,
  baz: tar

instead of:

var newObject = {
  foo: bar,
  baz: tar
return newObject

For Array#push() to have returned `this`, I can't think of a single line of
code it would have made simpler.

Another thing is that set() returning the value that was set is also
consistent with language semantics in that `(a = 1)` has the value of 1.

I'd like to see a better way to do chaining than functions returning
`this`, like the monocle mustache.


On Wed, Dec 5, 2012 at 3:30 AM, Andrea Giammarchi <
andrea.giammarchi at gmail.com> wrote:

> as discussed before, the problem with setDefault() approach you are
> suggesting is that the dict(), at least in JS, will be created in any case.
> var newDict = a.setDefault(k1, dict());
> above operation will invoke dict() regardless k1 was present or less and
> this is not good for anyone: RAM, CPU, GC, etc
> the initial pattern is and wants to be like that so that not a single
> pointless operation is performed when/if the key is already there.
> var o = obj.has(key) ? obj.get(key) : obj.set(key, dict()); // <== see
> dict, never called if key
> quick and dirty
> var o = obj.get(key) || obj.set(key, dict());
> With current pattern, and my only concern is that after this decision
> every other `set()` like pattern will return this even where not optimal, I
> have to do
> var o = obj.has(key) ? obj.get(key) : obj.set(key, dict()).get(key);
> meh ... but I can survive :D
> On Tue, Dec 4, 2012 at 4:49 PM, Tab Atkins Jr. <jackalmage at gmail.com>wrote:
>> On Mon, Dec 3, 2012 at 2:21 PM, Andrea Giammarchi
>> <andrea.giammarchi at gmail.com> wrote:
>> > IMHO, a set(key, value) should return the value as it is when you
>> address a
>> > value
>> >
>> > var o = m.get(k) || m.set(k, v); // o === v
>> >
>> > // equivalent of
>> >
>> > var o = m[k] || (m[k] = v); // o === v
>> If this pattern is considered sufficiently useful (I think it is), we
>> should handle it directly, as Python does.  Python dicts have a
>> setDefault(key, value) method which implements this pattern exactly -
>> if the key is in the dict, it returns its associated value (acts like
>> a plain get()); if it's not, it sets the key to the passed value and
>> then returns it.  Using this pattern is not only clearer, but avoids
>> repetition (of "m" and "k" in your example), and actually chains - I
>> use setDefault all the time when working with nested dicts.
>> (For example, if I have a sparse 2d structure implemented with nested
>> dicts, I can safely get/set a terminal value with code like
>> "a.setDefault(k1, dict()).set(k2, v)".  If that branch hadn't been
>> touched before, this creates the nested dict for me.  If it has, I
>> create a throwaway empty dict, which is cheap.  If JS ever grows
>> macros, you can avoid the junk dict as well.)
>> I prefer the plain methods to work as they are currently specified,
>> where they return this.
>> ~TJ
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121205/456b3792/attachment.html>

More information about the es-discuss mailing list