Shorthand for "function" keyword

Laurentiu Taschina source.spider at gmail.com
Mon Nov 13 22:22:15 UTC 2017


> Who uses functions instead of arrow functions and methods these days,
anyway? (I know, people who haven't adopted ES2015+)

In my previous message on the paragraph where I talked about how "let"
would suffer the same if it was longer I had some words about how we'll
eventually reach the stage where people actively avoid "function" by
abusing classes, objects and arrow functions everywhere, because they think
it's hip and cool even though it's mostly fluff with little concrete
benefit. It felt like too much of a tangent so scraped it. But...

Didn't think someone would post no mere 2 messages later on how we should
need to write a pointless class or anonymous function to get it. Seems I
should have just left that part in. :)

With regard to ES2015+ I actually do use the bleeding edge more or less of
the spec and also typescript on the server. I've used most of them more
then I can count.
I have my opinions on when and where some of features are useful. Some are
useful all the time, some only useful when used sparingly, and detract more
then they add.
Blindly just throw "new shiny features" of the language and you won't end
up with better code, you'll just end up with enterprise javascript
fizzbuzz. [1]

> Are you worried about typing more characters? Use an IDE with
auto-complete, or snippets.

The problem can not be easily fix'ed with snippets. I wasn't even pointing
at using "func" by the way, I've mentioned several from other languages as
examples.
So long as it's not over 4 characters (and it's not some convoluted symbol
character notation, or awkward letter positioning) I don't particularly
care which one is chosen.

*But anyway, lets say "fn" was used to denote named "arrow functions"
(technically we don't need the arrow in this case so I'll omit it in the
example). *

Take something like the following,

let sorter;
if (someCondition) {
    sorter = fn sortByA() {
        /* 100 lines of code */
    }
}
else {
    sorter = fn sortByA() {
        /* 100 lines of code */
    }
}


Closest equivalent code would be like this:

let sorter;
if (someCondition) {
    sorter = (function sortByA() {
        /* 100 lines of code */
    }).bind(this)
}
else {
    sorter = (function sortByA() {
        /* 100 lines of code */
    }).bind(this)
}


Though more realistically you would write it like this:

const self = this; // avoid the need for binding this
let sorter;
if (someCondition) {
    sorter = function sortByA() {
        /* 100 lines of code */
    }
}
else {
    sorter = function sortByA() {
        /* 100 lines of code */
    }
}

Hard to say which is more annoying, binding "this" everywhere or managing a
"self" as an alias to "this".

And if we really have to use our lord and savior arrow functions, the
closest equivalent is this:

let sorter;
if (someCondition) {
    const sortByA = () => {
        /* 100 lines of code */
    }

    sorter = sortByA;
}
else {
    const sortByA = () => {
        /* 100 lines of code */
    }

    sorter = sortByB;
}

Prettier but silly.

You see the same variable duplication problem with the more common case of
callbacks, be it to async functions or some sort of looping function:

each(migrations, fn mergeRequirements( /* ... */ ) {
    // much stuff
});


Earlier one a very clever workaround was suggested,

let mergeRequirements;
each(migrations, mergeRequirements = ( /* ... */ ) => {
    // much stuff
});


It's very clever, but of course in practice you'd never do it. It's just
awkward.

In the real world what I do for example is either prioritize never having
"this" as some requirement of any code if I can help it. Don't place your
helper functions as methods and suddenly no need for this.methodCall. When
practical, you can avoid the usual public methods by having functions and
passing the instance in rather then calling the method on the instance;
this is the right approach if your code with classes would just produce a
giant inheretence mess rather then anything useful. But of course IF
classes, or rather some sort of instantiatable type with methods attached
(since you can chose not use the "class" keyword and do it the old fashion
way if you want mixins), are actually the correct approach for representing
the thing in question, the solution with a "self" alias for "this" is the
easiest fix.

But really I shouldn't even have to do that at all, it should just work.

I won't go back on what I've already said, but my case isn't with just
arrow functions but normal "function" too. It's too long! hard to write,
hard to read. I would have to make ligatures for it get shorter in an IDE,
since when do we need IDEs anyway? (I use one but IDEs being that intrusive
is like depending on a intermediate language) Because it's long as I
described already, people just gravitate away from it; look at Naveen's
message. And when they have to use it, from my experience, the anonymous
version wins, because it's shorter. Anonymous functions aren't
exactly necessary, the most legitimate case I can think of is when it's so
short its the name is longer then the function itself, ie. (a, b) => a + b,
and these are rare, very rare in real life then compared to in blog
articles and whatnot (in my experience at least, but may be just a coding
style thing).



Actually with that in mind, if the shortnend versions REQUIRED a name every
time, that would actually be perfectly fine by me. I realize this would be
maybe a bit extreme, but there wouldn't be this "[no LineTerminator here]"
issue Cowder brought up earlier, since "func()" could only mean call to a
function "func" as there's no name there ;)

*Arrow functions already fill in the niche of shortest possible syntax to
express an anonymous function so it wouldn't be any "loss".*

--

[1] https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition


On Sun, Nov 12, 2017 at 5:53 PM, Isiah Meadows <isiahmeadows at gmail.com>
wrote:

> That sounds like a major V8 bug that [should be reported][1] - there
> should be zero performance difference between an arrow function and a
> normal ES5 function. They're completely equivalent apart from ES5
> functions being constructible and arrow functions forming a closure
> around the current call context. In particular, I'd expect them to be
> *faster*, not slower.
>
> [1]: https://bugs.chromium.org/p/v8/issues/list
> -----
>
> Isiah Meadows
> me at isiahmeadows.com
>
> Looking for web consulting? Or a new website?
> Send me an email and we can get started.
> www.isiahmeadows.com
>
>
> On Sun, Nov 12, 2017 at 5:45 AM, J Decker <d3ck0r at gmail.com> wrote:
> >
> >
> > On Sun, Nov 12, 2017 at 2:14 AM, T.J. Crowder
> > <tj.crowder at farsightsoftware.com> wrote:
> >>
> >> On Sun, Nov 12, 2017 at 9:56 AM, J Decker <d3ck0r at gmail.com> wrote:
> >> > Arrow functions passed as callback to Node.js addons execute 20%
> >> > slower than regular 'function()' functions.
> >>
> >> **Wow**. Is that written up somewhere one could read more?
> >>
> >> When you say "Node.js addon," are you excluding built-in Node APIs?
> >
> >
> > Basically it was an empty function I was calling with some simple
> parameters
> > It was only something I found through experimentation.  It really has
> > nothing to do with NodeJS other than it was an addon, it was just
> > interacting with the V8 engine.
> >
> > Writing file...
> > Wrote in  199  .. reading...
> > ()=>{} Read in ... 300000 3394
> > function(){} Read in ... 300000 2690
> >
> > https://github.com/d3x0r/sack.vfs/blob/master/tests/
> largeStreamtest.js#L15
> > and line 18 is the other one.
> > In the function I just increment a counter....  126% or 79.25%  ...but
> then
> > there is quite a bit of overhead in my library to parse the JSON. that's
> > quite a nested object
> > `{\"a${i}\":{\"b${i}\":{\"c${i}\":{\"d${i}\":123}}}}`
> > --------------
> > Hmm... changed the file that was being generated to just a simple string,
> > and the timings were closer (but was less than 1 second run) so I added
> some
> > generation counts and ran the tests in various orders... and I guess
> maybe
> > it was because of other factors that coincidentally showed as ()=>{}
> being
> > slower than function(){}
> >
> > function(){} Read in ... 100000 958
> > ()=>{} Read in ... 100000 906
> > ()=>{} Read in ... 100000 784
> > function(){} Read in ... 100000 783
> > ()=>{} Read in ... 100000 924
> > function(){} Read in ... 100000 779
> > function(){} Read in ... 100000 881
> > ()=>{} Read in ... 100000 805
> >
> > then just reversed the two tests in the original script and the timing
> > stayed the same in-order... but then would show function() as being the
> > slower one.
> >
> > My Bad; thanx for asking about that though I would have been stuck with
> that
> > misconception for a long time.
> >
> >
> >>
> >> -- T.J. Crowder
> >
> >
> >
> > _______________________________________________
> > 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20171114/77cb20ec/attachment-0001.html>


More information about the es-discuss mailing list