Function constants for Identity and No-op
Andrea Giammarchi
andrea.giammarchi at gmail.com
Wed Aug 10 14:32:17 UTC 2016
FWIW, I just use `Object` most of the time as both no-op and identity
(beside primitives, but I rarely have primitives on callback arguments
where I need the no-op).
I agree with Mark arrow makes everything ever more explicit and allocation
is an engine concern, something that could even not ever happen if it's
smart enough to transform no-ops into no-ops and identities into identities.
Just my 2 cents
On Wed, Aug 10, 2016 at 3:25 PM, Eli Perelman <eli at eliperelman.com> wrote:
> I can understand the sentiment of wanting brevity and avoiding unnecessary
> abstraction, but in some cases I think it comes at the cost of readability
> or good practice. This is why variables exist at all: to store commonly
> used values either for reuse or to cut down on unnecessary allocation.
>
> Sure, I could write code to ensure my numbers did go over a certain limit
> with `Math.min(userInput, 9007199254740991)`, but readability and
> abstraction give me something without having to keep this knowledge
> internally and create my own allocation, e.g. `Math.min(userInput,
> Math.MAX_SAFE_INTEGER`.
>
> Now obviously it would be trivial for me to declare these constants in
> userland code like I already do, e.g. `const NOOP = () => {}`, but in
> projects where it's needed in several files, I'll have to put that in a
> module or re-declare everywhere. This is not a huge inconvenience but
> something that could easily allocated for in the language.
>
> > The semantics of the named forms can be guessed rather well from the
> names, but one cannot be sure without looking up or remembering their
> definitions.
>
> This is true of anything; you know what you know, and are unsure of what
> you are unsure of. Those that understand what a no-ops and identity
> functions are will not need to look it up, and those that do not will look
> it up until they know it. Just like my personal enemies `Array#shift` and
> `Array#unshift`, I have to look those up every single time, and just
> because I can't remember which is which or their individual case doesn't
> mean they don't have value or that I resort to other tricks to avoid their
> usage. All that to say, I don't think lack of knowledge is a valid argument
> for these constants' non-inclusion. :)
>
> > Only pay these costs when the potential benefits are real.
>
> I think my allusion to potential benefits is avoidance of re-declaration
> (DRY) and allocation.
>
> Just my thoughts. :)
>
> Eli Perelman
>
>
>
> On Wed, Aug 10, 2016 at 9:08 AM Mark S. Miller <erights at google.com> wrote:
>
>> On Wed, Aug 10, 2016 at 2:10 AM, Isiah Meadows <isiahmeadows at gmail.com>
>> wrote:
>>
>>> I'll note that it's longer than just typing them out manually (and close
>>> if they're aliased):
>>>
>>> ```js
>>> Function.IDENTITY
>>> IDENTITY
>>> x => x
>>>
>>> Function.NOOP
>>> NOOP
>>> () => {}
>>> ```
>>>
>>> Not sure if it adds anything.
>>>
>>
>> Even aside from brevity, `x => x` and `() => {}` are more readable than
>> `Function.IDENTITY` and `Function.NOOP` for a very simple reason. The
>> semantics of the shorter forms are obvious and clear, give knowledge only
>> of the core language. The semantics of the named forms can be guessed
>> rather well from the names, but one cannot be sure without looking up or
>> remembering their definitions. As we all know, abstraction has tremendous
>> potential benefits. But it also has these costs -- the need to learn the
>> meaning of new definitions. Only pay these costs when the potential
>> benefits are real.
>>
>> Also, other things being equal, a briefer form is easier to read. In this
>> case, other things are not equal but both considerations point in the same
>> direction.
>>
>>
>>> On Tue, Aug 9, 2016, 14:44 Eli Perelman <eli at eliperelman.com> wrote:
>>>
>>>> I'm not sure if something like this has been proposed before, but I
>>>> often find myself declaring constants for the identity function and the
>>>> no-op function. I think it would be useful to have constants available on
>>>> Function containing these values. For example `Function.IDENTITY` and
>>>> `Function.NOOP`. Essentially these constants would map to:
>>>>
>>>> ```js
>>>> Function.IDENTITY = (a) => a;
>>>> Function.NOOP = () => null; // or:
>>>> Function.NOOP = () => {};
>>>> ```
>>>>
>>>> These could then be used in places where non-user-controlled APIs need
>>>> default functions need to be executed, or as placeholders for default
>>>> values that may be executed before a function has been supplied. For
>>>> example:
>>>>
>>>> ```js
>>>> // third-party API requires a callback or throws, but no functionality
>>>> really needs to done:
>>>> thirdParty.action(Function.NOOP);
>>>>
>>>> // Function needs a default which *may* execute prior to having a
>>>> different one specified (contrived):
>>>> const action = (handler = Function.IDENTITY, value = 10) =>
>>>> handler(value);
>>>> ```
>>>>
>>>> Thoughts? Seems like something simple with positive value. Thanks!
>>>>
>>>> Eli Perelman
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> es-discuss at mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
>>
>> --
>> Cheers,
>> --MarkM
>>
>
> _______________________________________________
> 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/20160810/c408fcb0/attachment-0001.html>
More information about the es-discuss
mailing list