In some cases inline functions (if they fall within V8 optimisations) can be re-used more cheaply than the overhead of non-inline alternatives like binding or currying
I use variable argument macro's to implement debug print functions for debugging. And I just leave them in the code as a form of documentation. Looking at the debug print statements tells you a lot of about what the code is doing.
> The use of trampolines requires an executable stack, which is a security risk. To avoid this problem, GCC also supports another strategy: using descriptors for nested functions. Under this model, taking the address of a nested function results in a pointer to a non-executable function descriptor object. Initializing the static chain from the descriptor is handled at indirect call sites.
> On some targets, including HPPA and IA-64, function descriptors may be mandated by the ABI or be otherwise handled in a target-specific way by the back end in its code generation strategy for indirect calls. GCC also provides its own generic descriptor implementation to support the -fno-trampolines option. In this case runtime detection of function descriptors at indirect call sites relies on descriptor pointers being tagged with a bit that is never set in bare function addresses. Since GCC’s generic function descriptors are not ABI-compliant, this option is typically used only on a per-language basis (notably by Ada) or when it can otherwise be applied to the whole program.
> For languages other than Ada, the -ftrampolines and -fno-trampolines options currently have no effect, and trampolines are always generated on platforms that need them for nested functions.
From: https://gcc.gnu.org/onlinedocs/gccint/Trampolines.html
You can actually do it in C, too! It just requires setting up a few macros, and getting it right requires a fairly decent understanding of the underlying hardware. (via TARGET_CUSTOM_FUNCTION_DESCRIPTORS).
The processors I program for don't have no execute stacks so the use of a trampoline is of no consequence.
Also my memory was that no execute stacks were heralded as the solution to stack smashing attacks. No execute stacks problem solved. And turned out if you're vulnerable to stack smashing no execute stacks won't save you.
So I feel we threw out something good, nested functions for some cargo cult security. And since no one uses them the reactionary luddites on WG14 are free to hope they go away.
My own personal approach in JavaScript is to avoid defining functions in a nested manner unless I explicitly want to capture a value from the enclosing scope.
This is probably due to an outdated mental model I had where it was shown in performance profiling that a function would be redefined every time the enclosing function was called. I doubt this is how any reasonable modern JavaScript interpreter works although I haven't kept up. Since the introduction of arrow functions (a long time ago now in relative terms) their prolific use has probably lead to deep optimizations that render this old mental model completely useless.
But old habits dies hard I guess and now I keep any named function that does not capture local variables at a file/module scope.
A lot of the other notes are interesting and very nit-picky in the "technically correct is the best kind of correct" way that older engineers eat up. I feel the general tone of carefulness that the NASA rules is trying to communicate to be very good and I would support most of them in the context that they are enforced.