What do you call a `function` function?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

What do you call a `function` function?

T.J. Crowder-2
Bit of a silly one, but begging the list's indulgence:

I routinely explain various JavaScript topics to learners, including arrow functions, method syntax, etc. When I want to contrast "arrow function" (for instance) with functions defined with `function`, it trips me up, and often I end up saying/writing something awful like "`function` function". I've considered using "normal function" instead, but arrow functions are normal in today's world, as are functions defined with method syntax (although I'd usually call them methods), so it's...unsatisfying.

But `function` function is just so clumsy. And a pedant (none of those here, surely!) could argue the definition (are generators `function` functions? they're defined with `function` [when you're not using generator method syntax], it just has a `*` after it).

I've also considered "old-style function," but `function` functions still have a place in today's JavaScript, just not as prominent a place as they used to.

A recent post to the list used "conventional function," but it may well have the same problems "normal function" does.

My goal is to be clear, and *reasonably* accurate, without being overly pedantic.

Any ideas? Should I just stop worrying and learn to love "normal function"? Is there a better term?

Thanks in advance, folks.

-- T.J. Crowder

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: What do you call a `function` function?

Eli Perelman
I've always referenced them as:

Function declarations:

function a() {} 

Function expression:

const a = function() {} 

Named function expression:

const b = function a() {} 

Arrow function:

const a = () => {} 

Not sure it's 100% semantic or descriptive, but it's how I've differentiated. 

Eli Perelman

On Sat, Apr 7, 2018, 12:56 PM T.J. Crowder <[hidden email]> wrote:
Bit of a silly one, but begging the list's indulgence:

I routinely explain various JavaScript topics to learners, including arrow functions, method syntax, etc. When I want to contrast "arrow function" (for instance) with functions defined with `function`, it trips me up, and often I end up saying/writing something awful like "`function` function". I've considered using "normal function" instead, but arrow functions are normal in today's world, as are functions defined with method syntax (although I'd usually call them methods), so it's...unsatisfying.

But `function` function is just so clumsy. And a pedant (none of those here, surely!) could argue the definition (are generators `function` functions? they're defined with `function` [when you're not using generator method syntax], it just has a `*` after it).

I've also considered "old-style function," but `function` functions still have a place in today's JavaScript, just not as prominent a place as they used to.

A recent post to the list used "conventional function," but it may well have the same problems "normal function" does.

My goal is to be clear, and *reasonably* accurate, without being overly pedantic.

Any ideas? Should I just stop worrying and learn to love "normal function"? Is there a better term?

Thanks in advance, folks.

-- T.J. Crowder
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: What do you call a `function` function?

Naveen Chawla
"function" function is the best out of all of the alternatives you mentioned.

"Anonymous function declared with the function keyword" if it's not too wordy.

On Sat, 7 Apr 2018 at 23:50 Eli Perelman <[hidden email]> wrote:
I've always referenced them as:

Function declarations:

function a() {} 

Function expression:

const a = function() {} 

Named function expression:

const b = function a() {} 

Arrow function:

const a = () => {} 

Not sure it's 100% semantic or descriptive, but it's how I've differentiated. 

Eli Perelman


On Sat, Apr 7, 2018, 12:56 PM T.J. Crowder <[hidden email]> wrote:
Bit of a silly one, but begging the list's indulgence:

I routinely explain various JavaScript topics to learners, including arrow functions, method syntax, etc. When I want to contrast "arrow function" (for instance) with functions defined with `function`, it trips me up, and often I end up saying/writing something awful like "`function` function". I've considered using "normal function" instead, but arrow functions are normal in today's world, as are functions defined with method syntax (although I'd usually call them methods), so it's...unsatisfying.

But `function` function is just so clumsy. And a pedant (none of those here, surely!) could argue the definition (are generators `function` functions? they're defined with `function` [when you're not using generator method syntax], it just has a `*` after it).

I've also considered "old-style function," but `function` functions still have a place in today's JavaScript, just not as prominent a place as they used to.

A recent post to the list used "conventional function," but it may well have the same problems "normal function" does.

My goal is to be clear, and *reasonably* accurate, without being overly pedantic.

Any ideas? Should I just stop worrying and learn to love "normal function"? Is there a better term?

Thanks in advance, folks.

-- T.J. Crowder
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: What do you call a `function` function?

C. Scott Ananian
"keyword function" might not be too bad, either...
 --scott

On Sat, Apr 7, 2018 at 2:32 PM, Naveen Chawla <[hidden email]> wrote:
"function" function is the best out of all of the alternatives you mentioned.

"Anonymous function declared with the function keyword" if it's not too wordy.

On Sat, 7 Apr 2018 at 23:50 Eli Perelman <[hidden email]> wrote:
I've always referenced them as:

Function declarations:

function a() {} 

Function expression:

const a = function() {} 

Named function expression:

const b = function a() {} 

Arrow function:

const a = () => {} 

Not sure it's 100% semantic or descriptive, but it's how I've differentiated. 

Eli Perelman


On Sat, Apr 7, 2018, 12:56 PM T.J. Crowder <[hidden email]> wrote:
Bit of a silly one, but begging the list's indulgence:

I routinely explain various JavaScript topics to learners, including arrow functions, method syntax, etc. When I want to contrast "arrow function" (for instance) with functions defined with `function`, it trips me up, and often I end up saying/writing something awful like "`function` function". I've considered using "normal function" instead, but arrow functions are normal in today's world, as are functions defined with method syntax (although I'd usually call them methods), so it's...unsatisfying.

But `function` function is just so clumsy. And a pedant (none of those here, surely!) could argue the definition (are generators `function` functions? they're defined with `function` [when you're not using generator method syntax], it just has a `*` after it).

I've also considered "old-style function," but `function` functions still have a place in today's JavaScript, just not as prominent a place as they used to.

A recent post to the list used "conventional function," but it may well have the same problems "normal function" does.

My goal is to be clear, and *reasonably* accurate, without being overly pedantic.

Any ideas? Should I just stop worrying and learn to love "normal function"? Is there a better term?

Thanks in advance, folks.

-- T.J. Crowder
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: What do you call a `function` function?

Isiah Meadows-2
I just call them "regular functions", "function declarations", or
similar. I'll add "arrow" if there's an arrow, and "async" if there's
an `async` keyword.
-----

Isiah Meadows
[hidden email]

Looking for web consulting? Or a new website?
Send me an email and we can get started.
www.isiahmeadows.com


On Sat, Apr 7, 2018 at 5:14 PM, C. Scott Ananian <[hidden email]> wrote:

> "keyword function" might not be too bad, either...
>  --scott
>
> On Sat, Apr 7, 2018 at 2:32 PM, Naveen Chawla <[hidden email]> wrote:
>>
>> "function" function is the best out of all of the alternatives you
>> mentioned.
>>
>> "Anonymous function declared with the function keyword" if it's not too
>> wordy.
>>
>> On Sat, 7 Apr 2018 at 23:50 Eli Perelman <[hidden email]> wrote:
>>>
>>> I've always referenced them as:
>>>
>>> Function declarations:
>>>
>>> function a() {}
>>>
>>> Function expression:
>>>
>>> const a = function() {}
>>>
>>> Named function expression:
>>>
>>> const b = function a() {}
>>>
>>> Arrow function:
>>>
>>> const a = () => {}
>>>
>>> Not sure it's 100% semantic or descriptive, but it's how I've
>>> differentiated.
>>>
>>> Eli Perelman
>>>
>>>
>>> On Sat, Apr 7, 2018, 12:56 PM T.J. Crowder
>>> <[hidden email]> wrote:
>>>>
>>>> Bit of a silly one, but begging the list's indulgence:
>>>>
>>>> I routinely explain various JavaScript topics to learners, including
>>>> arrow functions, method syntax, etc. When I want to contrast "arrow
>>>> function" (for instance) with functions defined with `function`, it trips me
>>>> up, and often I end up saying/writing something awful like "`function`
>>>> function". I've considered using "normal function" instead, but arrow
>>>> functions are normal in today's world, as are functions defined with method
>>>> syntax (although I'd usually call them methods), so it's...unsatisfying.
>>>>
>>>> But `function` function is just so clumsy. And a pedant (none of those
>>>> here, surely!) could argue the definition (are generators `function`
>>>> functions? they're defined with `function` [when you're not using generator
>>>> method syntax], it just has a `*` after it).
>>>>
>>>> I've also considered "old-style function," but `function` functions
>>>> still have a place in today's JavaScript, just not as prominent a place as
>>>> they used to.
>>>>
>>>> A recent post to the list used "conventional function," but it may well
>>>> have the same problems "normal function" does.
>>>>
>>>> My goal is to be clear, and *reasonably* accurate, without being overly
>>>> pedantic.
>>>>
>>>> Any ideas? Should I just stop worrying and learn to love "normal
>>>> function"? Is there a better term?
>>>>
>>>> Thanks in advance, folks.
>>>>
>>>> -- T.J. Crowder
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> [hidden email]
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [hidden email]
>>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> [hidden email]
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: What do you call a `function` function?

Darien Valentine
In reply to this post by T.J. Crowder-2
I usually say "function function," but yeah ... it’s painful haha. I sometimes work with devs whose experience with ES functions is limited to methods and arrow functions, so "normal function" doesn’t really fly anymore. I’ve considered "classic function," but that probably wouldn’t help much.

I have no good answer to the root question here, but I’ve thought about this a bit. There seem to be many ways we could categorize and name "types of functions" in ES and the best choices probably vary with context / audience.

# 1. Naming after syntactic productions

The ES spec includes the following relevant named syntactic productions. So the nice thing about using a taxonomy based on syntax is that it minimizes subjective factors and matches up fairly well with how many people think about code:

- ArrowFunction
- AsyncArrowFunction
- AsyncFunctionDeclaration
- AsyncFunctionExpression
- AsyncGeneratorDeclaration
- AsyncGeneratorExpression
- ClassDeclaration
- ClassExpression
- FunctionDeclaration
- FunctionExpression
- GeneratorDeclaration
- GeneratorExpression
- MethodDefinition

The ClassDeclaration and ClassExpression ones are a bit fuzzy, since an _explicit_ constructor is a MethodDefinition syntactically, but ClassDeclarations and ClassExpressions without explicit constructor MethodDeclarations do still create functions. In any case, the fact that `constructor` is a MethodDeclaration is an example of a shortcoming of this approach: a constructor is specifically _not_ usable as a method in the sense that we usually mean, so you really feel the "these are just names for the grammar" factor there.

Another concern might be that syntax is not the only means by which functions are created, so it we don’t get a corresponding name for everything. Use of the four Function constructors, bound function exotic objects, and Proxies are also avenues by which new callable/constructable objects can be created, but they have no syntactic expression, so they might be awkward to categorize along these lines.

In this taxonomy, the name would be "function declaration" or "function expression". That doesn’t actually address the ambiguity problem around unless everybody is on the same page, so I think this angle is not very good.

# 2. Functions by class

All function objects (or at least all non-"extrinsic" ones) will report themselves as instances of one of these four corresponding constructors from their Realm:

- %AsyncFunction% (`(async function() {}).constructor`)
- %AsyncGeneratorFunction% (`(async function * () {}).constructor`)
- %Function% (`Function`)
- %GeneratorFunction% (`(function * () {}).constructor`)

In this taxonomy, we get to place every (or very nearly every) function into a category without trouble. On one hand, these are the most dramatic "function type" distinctions we can draw, so it isn’t-not-useful — but it doesn’t give us a way to talk about distinctions between functions created with class syntax, arrow syntax, etc, so it’s also a nonstarter.

# 3. What constitutes a type of function

I’m figuring that underlying the communication problem is a different issue: what constitutes a "type of function" in ES may not really have a simple and objective answer.

For example, from a syntactic POV, FunctionDeclaration and FunctionExpression are different in several ways, like how their names may be derived, what/whether bindings are created and in what scope, and whether hoisting takes place. But looked at as values (that is, considering just the function objects that the syntax creates), these two forms end up exhibiting no observable behavioral differences. Given that some functions do possess contrasting semantics that are _very_ observable, like async functions, can we really say a FunctionDeclaration and FunctionExpression are different "types" on the same order?

I think the best answer is no — they are, instead, different syntactic forms for describing what should be considered the same type of function. So let’s look at what behaviors of the functions themselves, rather than the syntax used, really can differ, because maybe there’s a better answer there.

# 4. Functions by semantics

The distinction between arrow functions and non-arrow functions (of various types) is that their [[ThisMode]] is "lexical" and the others are not — but the there are actually two other [[ThisMode]] values, "global" and "strict". It is not simply a binary distinction between lexical and non-lexical "this" because functions created in sloppy mode may resolve "this" to the global object and functions created in strict mode may not.

(Bear with me alright ^_^;)

Related to (but not directly corresponding to) the "functions by class" section, there is a [[FunctionKind]] slot. Its value may be "normal", "classConstructor", "generator", or "async". During function allocation, other similar values are transiently in the mix, like "non-constructor" (which prevents the allowance of a [[Construct]] method for an otherwise "normal" function), and "async generator" (which becomes "generator"); during function initialization there are also "Arrow", "Normal" and "Method". But I mention these only to clarify that they are used to set other properties (e.g. Arrow leads to setting [[ThisMode]] to "lexical") — they don’t remain "part" of the function like [[FunctionKind]] does.

So both the "classConstructor" and "normal" kinds correspond to %Function%, while both %AsyncGeneratorFunction% and %GeneratorFunction% correspond to "generator". Whew.

(I’ve probably got some details wrong there, but I think it’s _mostly_ accurate.)

Two fundamental forms correspond to _constructable_ functions:

- `class Foo {}`, `(class {})`
- `function Foo() {}`, `(function() {})`, `new Function()`

These types of functions obtain a `prototype` property when they are created.

In addition a bound function exotic object will be constructable if the function it proxies is constructable.

All other functions are not constructable — this is the distinction between `function foo() {}` and the method `foo() {}` (it’s not sugar). But async functions, generators, and async generators are never constructable in any of their syntactic forms — declarations, expressions/arrows, methods — so for those, method syntax _is_ just sugar — or rather would be, if not for one last key slot, [[HomeObject]], which exists only for methods and affords them the ability to use super expressions. You know ... writing it all out like this makes it suddenly feel _very_ complicated @_@.

As for [[Call]], all functions possess this internal method, even classes; however, if the [[FunctionKind]] is "classConstructor", then an attempt to use [[Call]] will always throw, making it _effectively_ unavailable. What this means in practice is that the unique property of `function` functions is that they are the only functions which can be both called and constructed (not counting black magic that makes other functions _seem_ to have both capabilities).

Putting [[HomeObject]] (which doesn’t seem like a "type" issue so much) and bound function exotic objects (which are more or less proxies to other functions) aside, we could say there are three abstract semantic attributes that contribute significantly to what we as language users typically think of as "function type":

- presence of [[Construct]]
- value of [[FunctionKind]]
- value of [[ThisMode]]

At the loss of some precision, we can conflate "global" and "strict" [[ThisMode]] since, admittedly, we don’t often think about this and they don’t correspond to any specific syntax. What we get in this taxonomic model then is a matrix with three dimensions. The first column is [[FunctionKind]], the second is whether [[Construct]] exists (the extra axis), and then horizontally we have [[ThisMode]]. Cells with "-" describe combinations that aren’t possible, while the others provide (non-exhaustive) examples of corresponding syntax.

(I’m not sure if ES discuss will let me include a GFM table, and I imagine some people look at this via email, so here’s an alternative link: https://gist.github.com/bathos/6bb1e5ef92d2c8f89363c0931d048caf)

| FK               | Cstr | TM: Lexical    | TM: Global / Strict               |
|------------------|------|----------------|-----------------------------------|
| normal           | cstr | -              | function() {}; new Function       |
| normal           | no   | () => {}       | x() {}                            |
| classConstructor | cstr | -              | class {}                          |
| classConstructor | no   | -              | -                                 |
| generator        | cstr | -              | -                                 |
| generator        | no   | -              | function * () {}; * x() {}        |
| async            | cstr | -              | -                                 |
| async            | no   | async () => {} | async function() {}; async x() {} |

If we do turn the non-empty cells into a list, we get seven types of functions. If we label them by the primary facets that make each _semantically unique,_ we end up with a final taxonomy that would look something like this:

- lexical function
- async lexical function
- callable constructor
- method
- constructor
- generator / generator method
- async function / async method

So circling back to the original question, I got "callable constructor"! (record scratch) Eh...

Okay, I guess that isn’t gonna catch on haha. It may more accurately reflect what makes `function`-keyword-functions unique, but given common usage patterns, it would be too confusing. Inversion could help a little ("constructable function"), but not enough.

Anyway, it’s just a little investigation. Nobody’s gonna start using these terms. But it was interesting to think about and you’re not alone in sometimes struggling to find the best terminology for different kinds of functions that ES developers with diverse experience levels all find clear.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: What do you call a `function` function?

T.J. Crowder-2
In reply to this post by T.J. Crowder-2
**Wow**, thanks everyone for all the input!!

I woke up this morning with "classic function" in my head, and immediately worried about confusing people (particularly those for whom English is not their native tongue) with `class`, since it creates a function (the constructor).

So I'm currently leaning toward Raul-Sebastian's "traditional function" (thank you!) since it largely conveys the same meaning as "classic" without the `class` problem.

So taking a page from Darien's magnum opus :-) I get:

* Traditional function (`function` declaration, `function` expression)
* Constructor (for both `class` and `function` when the intent is to create a constructor; draw a distinction when necessary)
* Method (some vagueness here, we used to use "method" to refer to traditional functions assigned as object properties, but of course, we got methods with discernable differences -- can't be constructors, can use `super` -- in ES2015)
* Arrow function
* `async` function
* `async` arrow function
* Generator function
* `async` generator function

I think this mostly conveys useful meaning, without getting too pedantic.

Again, thank you everyone for the very useful responses!

-- T.J. Crowder

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss