On Wed, Aug 10, 2016 at 7:33 AM, Mark S. Miller <erig...@google.com> wrote:
> > > On Wed, Aug 10, 2016 at 7:25 AM, Eli Perelman <e...@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`. >> > > 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 <erig...@google.com> >> wrote: >> >>> On Wed, Aug 10, 2016 at 2:10 AM, Isiah Meadows <isiahmead...@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 <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 list >>>> es-discuss@mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >>> >>> -- >>> Cheers, >>> --MarkM >>> >> > > > -- > Cheers, > --MarkM > -- Cheers, --MarkM
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss