Re: Function constants for Identity and No-op

2016-08-10 Thread Alexander Jones
Those spellings don't help when trying to visually parse a bunch of code
which already largely consists of dense punctuation, though, IMO.

On Wednesday, 10 August 2016, Tab Atkins Jr.  wrote:

> On Wed, Aug 10, 2016 at 7:25 AM, Eli Perelman  > wrote:
> > 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.
>
> Mark's argument (which I agree with) is that `x=>x` and `()=>{}` are
> good *spellings* of "identity function" and "noop function".  It's
> immediately obvious what they do; `obj.doCallback(()=>{})` is about as
> easy to understand as `obj.doCallback(Function.noop)`.  The ID
> function is even simpler - `obj.map(x=>x)` reads *extremely* well to
> me, equal or better than `obj.map(Function.id)`. If we were to reserve
> "id" and "noop" as bare global variables, I might agree that those
> were even better, but that's clearly out of the question.
>
> ~TJ
> ___
> es-discuss mailing list
> es-discuss@mozilla.org 
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Tab Atkins Jr.
On Wed, Aug 10, 2016 at 7:25 AM, Eli Perelman  wrote:
> 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.

Mark's argument (which I agree with) is that `x=>x` and `()=>{}` are
good *spellings* of "identity function" and "noop function".  It's
immediately obvious what they do; `obj.doCallback(()=>{})` is about as
easy to understand as `obj.doCallback(Function.noop)`.  The ID
function is even simpler - `obj.map(x=>x)` reads *extremely* well to
me, equal or better than `obj.map(Function.id)`. If we were to reserve
"id" and "noop" as bare global variables, I might agree that those
were even better, but that's clearly out of the question.

~TJ
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Andrea Giammarchi
Kevin that "from somewhere else" has same problems cross-realm `instanceof`
would have, you can't always trust that and if you want to map identities
just do it instead of adding extra code ;-)

On Wed, Aug 10, 2016 at 5:24 PM, Kevin Reid  wrote:

> [no quotes because I'm not replying to anyone in particular]
>
> An advantage that has not been mentioned yet, of having a canonical
> function instance for particular behaviors, is that it allows for some
> library-level optimization by being able to know what a function does
> (which is otherwise opaque). For a simple example:
>
> SomeKindOfImmutableCollection.prototype.map = function (f) {
> if (f === Function.IDENTITY) {
> return this;
> }
> ...build a new collection with f applied to elements and return it...
> };
>
> Of course, it would be silly to write coll.map(Function.IDENTITY), but a
> caller might be passing the function from somewhere else.
>
> (I only intend to point out this one benefit, not to claim it justifies
> the feature entirely.)
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Kevin Reid
[no quotes because I'm not replying to anyone in particular]

An advantage that has not been mentioned yet, of having a canonical
function instance for particular behaviors, is that it allows for some
library-level optimization by being able to know what a function does
(which is otherwise opaque). For a simple example:

SomeKindOfImmutableCollection.prototype.map = function (f) {
if (f === Function.IDENTITY) {
return this;
}
...build a new collection with f applied to elements and return it...
};

Of course, it would be silly to write coll.map(Function.IDENTITY), but a
caller might be passing the function from somewhere else.

(I only intend to point out this one benefit, not to claim it justifies the
feature entirely.)
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Allen Wirfs-Brock

> On Aug 10, 2016, at 8:46 AM, Peter van der Zee  wrote:
> 
> There is precedent (at least in IE [1]) for exotic functions where
> `typeof` returned "unknown". Could happen for any exotic value unless
> >>the spec changed on that<<. 

see 
https://tc39.github.io/ecma262/#sec-typeof-operator-runtime-semantics-evaluation
 

 


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Michał Wadas
Function.isFunction was a joke, I'm pretty sure that only very old legacy
code deals with document.all and crazy stuff like that (however, it would
be useful, but saving me from typing few more characters isn't something
urgent or important).

On 10 Aug 2016 5:46 p.m., "Peter van der Zee"  wrote:

> >> What's the issue with document.createElement('object')?
>
> > It's a callable exotic object.
>
> >> Function.isFunction? :D
>
> > typeof is what you are looking for.
>
> There is precedent (at least in IE [1]) for exotic functions where
> `typeof` returned "unknown". Could happen for any exotic value unless
> the spec changed on that. An `isFunction`, or rather, a simple
> `isCallable`, may not be that far off the mark and is in line with the
> existing `isArray`. Though I'd much rather have callables invariantly
> locked down to being "typeof function". Even if that means explicit
> exceptions to some legacy cases.
>
> - peter
>
> PS. Regexes in firefox were "callable" and had typeof function, but I
> think that's so far back [2] it's not super relevant here. Of course
> the same could be said about the IE case.
>
> [1]; one of many examples:
> http://stackoverflow.com/questions/10982739/typeof-returning-unknown-in-ie
> [2]; https://bugzilla.mozilla.org/show_bug.cgi?id=61911
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Peter van der Zee
>> What's the issue with document.createElement('object')?

> It's a callable exotic object.

>> Function.isFunction? :D

> typeof is what you are looking for.

There is precedent (at least in IE [1]) for exotic functions where
`typeof` returned "unknown". Could happen for any exotic value unless
the spec changed on that. An `isFunction`, or rather, a simple
`isCallable`, may not be that far off the mark and is in line with the
existing `isArray`. Though I'd much rather have callables invariantly
locked down to being "typeof function". Even if that means explicit
exceptions to some legacy cases.

- peter

PS. Regexes in firefox were "callable" and had typeof function, but I
think that's so far back [2] it's not super relevant here. Of course
the same could be said about the IE case.

[1]; one of many examples:
http://stackoverflow.com/questions/10982739/typeof-returning-unknown-in-ie
[2]; https://bugzilla.mozilla.org/show_bug.cgi?id=61911
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Mark S. Miller
On Wed, Aug 10, 2016 at 7:33 AM, Mark S. Miller  wrote:

>
>
> On Wed, Aug 10, 2016 at 7:25 AM, Eli Perelman  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`.
>>
>
> My message is about tradeoffs -- weighing costs against benefits. The
> costs I raise are cognitive burden.
>
> `x => x` has lower cognitive burden than `Function.IDENTITY`
> `9007199254740991` has much higher cognitive burden than
> `Math.MAX_SAFE_INTEGER`
> `3.141592653589793` has much higher cognitive burden than `Math.PI`
> `3` has lower cognitive burden than `Math.THREE`
>
>
>
>
>>
>> Now obviously it would be trivial for me to declare these constants in
>> userland code like I already do, e.g. `const NOOP = () => {}`
>>
>
>
> If there was a reason to do that, then it might make sense to consolidate
> these. However, this definition looks to me like a userland
>
> `const THREE = Math.THREE;`
>

Meant:

const THREE = 3;




>
> Whether in userland or not, such an "abstraction" only subtracts value.
>
>
>
>
>> , 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 
>> wrote:
>>
>>> On Wed, Aug 10, 2016 at 2:10 AM, Isiah Meadows 
>>> 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  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

Re: Function constants for Identity and No-op

2016-08-10 Thread Kris Siegel
I agree with Mark here plus we have const now which is perfect for
something like this if you wanted to take DRY to an extreme.

Ultimately seeing a function declared is obvious, seeing a special key word
is not. I have been in software development close to 15 years now and when
I first saw this I had to look up to remind myself what identity and noop
referred to (used the concepts many times but frequently forget what
they're called).

Sometimes DRY can be taken too far. This is one of those times IMO.

On Aug 10, 2016 7:33 AM, "Mark S. Miller"  wrote:

>
>
> On Wed, Aug 10, 2016 at 7:25 AM, Eli Perelman  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`.
>>
>
> My message is about tradeoffs -- weighing costs against benefits. The
> costs I raise are cognitive burden.
>
> `x => x` has lower cognitive burden than `Function.IDENTITY`
> `9007199254740991` has much higher cognitive burden than
> `Math.MAX_SAFE_INTEGER`
> `3.141592653589793` has much higher cognitive burden than `Math.PI`
> `3` has lower cognitive burden than `Math.THREE`
>
>
>
>
>>
>> Now obviously it would be trivial for me to declare these constants in
>> userland code like I already do, e.g. `const NOOP = () => {}`
>>
>
>
> If there was a reason to do that, then it might make sense to consolidate
> these. However, this definition looks to me like a userland
>
> `const THREE = Math.THREE;`
>
> Whether in userland or not, such an "abstraction" only subtracts value.
>
>
>
>
>> , 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 
>> wrote:
>>
>>> On Wed, Aug 10, 2016 at 2:10 AM, Isiah Meadows 
>>> 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  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` 

RE: Function constants for Identity and No-op

2016-08-10 Thread Domenic Denicola
From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Mark S. 
Miller

> What's the issue with document.createElement('object')?

It's a callable exotic object.

>> On Wed, Aug 10, 2016 at 7:20 AM, Michał Wadas  
>> wrote:
>> Function.isFunction? :D

typeof is what you are looking for.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Mark S. Miller
On Wed, Aug 10, 2016 at 7:25 AM, Eli Perelman  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`.
>

My message is about tradeoffs -- weighing costs against benefits. The costs
I raise are cognitive burden.

`x => x` has lower cognitive burden than `Function.IDENTITY`
`9007199254740991` has much higher cognitive burden than
`Math.MAX_SAFE_INTEGER`
`3.141592653589793` has much higher cognitive burden than `Math.PI`
`3` has lower cognitive burden than `Math.THREE`




>
> Now obviously it would be trivial for me to declare these constants in
> userland code like I already do, e.g. `const NOOP = () => {}`
>


If there was a reason to do that, then it might make sense to consolidate
these. However, this definition looks to me like a userland

`const THREE = Math.THREE;`

Whether in userland or not, such an "abstraction" only subtracts value.




> , 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  wrote:
>
>> On Wed, Aug 10, 2016 at 2:10 AM, Isiah Meadows 
>> 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  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 

Re: Function constants for Identity and No-op

2016-08-10 Thread Andrea Giammarchi
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  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  wrote:
>
>> On Wed, Aug 10, 2016 at 2:10 AM, Isiah Meadows 
>> 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  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
 

Re: Function constants for Identity and No-op

2016-08-10 Thread Eli Perelman
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  wrote:

> On Wed, Aug 10, 2016 at 2:10 AM, Isiah Meadows 
> 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  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@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
>
> --
> Cheers,
> --MarkM
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Mark S. Miller
What's the issue with document.createElement('object')?


On Wed, Aug 10, 2016 at 7:20 AM, Michał Wadas  wrote:

> Using instanceof Function can be confusing, because there are objects
> that are callable but not instanceof Function (document.all,
> document.createElement('object'), any cross-realm function).
>
> Function.isFunction? :D
>
> On Wed, Aug 10, 2016 at 4:00 PM, Mark S. Miller 
> wrote:
>
>>
>>
>> On Wed, Aug 10, 2016 at 4:53 AM, Andy Earnshaw 
>> wrote:
>>
>>> On Wed, 10 Aug 2016 at 12:42 Michał Wadas  wrote:
>>>
 Function.prototype is no-op (run Function.prototype.toString() for
 more information)

>>>
>>> That's true, but using `Function.prototype` can be confusing
>>>
>>
>> Indeed.
>>
>> > Function.prototype instanceof Function
>> false
>>
>>
>>
>>> when passed to a function as a callback:
>>>
>>> someFunc(Function.prototype);
>>>
>>> It's not immediately clear that `someFunc` is expecting a callback
>>> function in this case, whereas `Function.NOOP` or `() => {}` are pretty
>>> obvious.
>>>
>>> ___
>>> es-discuss mailing list
>>> es-discuss@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
>>
>> --
>> Cheers,
>> --MarkM
>>
>
>


-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Michał Wadas
Using instanceof Function can be confusing, because there are objects that
are callable but not instanceof Function (document.all,
document.createElement('object'), any cross-realm function).

Function.isFunction? :D

On Wed, Aug 10, 2016 at 4:00 PM, Mark S. Miller  wrote:

>
>
> On Wed, Aug 10, 2016 at 4:53 AM, Andy Earnshaw 
> wrote:
>
>> On Wed, 10 Aug 2016 at 12:42 Michał Wadas  wrote:
>>
>>> Function.prototype is no-op (run Function.prototype.toString() for more
>>> information)
>>>
>>
>> That's true, but using `Function.prototype` can be confusing
>>
>
> Indeed.
>
> > Function.prototype instanceof Function
> false
>
>
>
>> when passed to a function as a callback:
>>
>> someFunc(Function.prototype);
>>
>> It's not immediately clear that `someFunc` is expecting a callback
>> function in this case, whereas `Function.NOOP` or `() => {}` are pretty
>> obvious.
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
>
> --
> Cheers,
> --MarkM
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Mark S. Miller
On Wed, Aug 10, 2016 at 2:10 AM, Isiah Meadows 
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  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@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>


-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Mark S. Miller
On Wed, Aug 10, 2016 at 4:53 AM, Andy Earnshaw 
wrote:

> On Wed, 10 Aug 2016 at 12:42 Michał Wadas  wrote:
>
>> Function.prototype is no-op (run Function.prototype.toString() for more
>> information)
>>
>
> That's true, but using `Function.prototype` can be confusing
>

Indeed.

> Function.prototype instanceof Function
false



> when passed to a function as a callback:
>
> someFunc(Function.prototype);
>
> It's not immediately clear that `someFunc` is expecting a callback
> function in this case, whereas `Function.NOOP` or `() => {}` are pretty
> obvious.
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>


-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Andy Earnshaw
On Wed, 10 Aug 2016 at 12:42 Michał Wadas  wrote:

> Function.prototype is no-op (run Function.prototype.toString() for more
> information)
>

That's true, but using `Function.prototype` can be confusing when passed to
a function as a callback:

someFunc(Function.prototype);

It's not immediately clear that `someFunc` is expecting a callback function
in this case, whereas `Function.NOOP` or `() => {}` are pretty obvious.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Michał Wadas
Function.prototype is no-op (run Function.prototype.toString() for more
information)

On Wed, Aug 10, 2016 at 12:03 PM, Tiddo Langerak 
wrote:

> I think this is more about improving readability than saving a few
> characters.
>
>
> On 08/10/2016 11:10 AM, Isiah Meadows 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.
>
> On Tue, Aug 9, 2016, 14:44 Eli Perelman < 
> e...@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@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>
> ___
> es-discuss mailing 
> listes-discuss@mozilla.orghttps://mail.mozilla.org/listinfo/es-discuss
>
>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Tiddo Langerak
I think this is more about improving readability than saving a few 
characters.


On 08/10/2016 11:10 AM, Isiah Meadows 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.


On Tue, Aug 9, 2016, 14:44 Eli Perelman > 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@mozilla.org 
https://mail.mozilla.org/listinfo/es-discuss



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Isiah Meadows
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.

On Tue, Aug 9, 2016, 14:44 Eli Perelman  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@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss