Open Haringat opened 2 years ago
Why would we need to differentiate? Its a call if there’s invoking parens, it’s not if there’s not.
@ljharb Because that is not true in the examples stated above because the ::
operator could also be used for property binding as described in the first example.
ah, i see what you mean.
This seems like it would be penalizing all the common cases in service of avoiding the need for parens in one exceedingly rare use case.
I am not sure but maybe it could be arranged that for ::
the parens are optional so that
const x = value::func;
and
const x = value::func();
would be identical and both desugar to
const x = func.bind(value);
That would be far, far worse. The former should only bind, and the latter should only call, and the mistake made with new
where invoking parens are optional should never be repeated.
Using higher-order functions at all is rare; using receiver-sensitive higher-order functions should be almost nonexistent. Just use parens for these cases.
@ljharb and how would you create parameter bindings with that approach? Say, you want to fix the first argument to a set value and only want the function to be called with the other arguments. Here is an example that comes to mind:
function logValue(prefix, loggable) {
this.log(prefix + loggable);
}
values.forEach(console::logValue("prefix: "));
ok so, a few things. First of all, I simply wouldn't do that, because it's a standalone function and shouldn't use this
at all. However, if I had to for some reason, I'd do values.forEach(logValue.bind(console, 'prefix: '))
. iow, this syntax is explicitly NOT intended to allow you to bind arguments, only the receiver.
Where does it state that the syntax was explicitly not intended for that?
The entire readme discusses the receiver and doesn't mention arguments, for seven years, as does the strawman linked in the readme, via archive.org which dates back many years before that.
"it does not state anything about that" is not the same as "it is explicitly not intended for that". Explicit would mean that it actually states somewhere that this is not supposed to work.
Fair enough, it doesn’t state it. But through every discussion of it I’ve been present for, it was explicitly the purpose.
This isn't needed. Instead of value:::func(arguments)
this could be used value::func()(arguments)
.
@Pro2stinger this would require func
to always return a bound function. This would be a hassle to write, at which point using Function.prototype.call
would actually be more convenient.
To better differentiate between "bind and call" and "only bind, but do not call" I would introduce a new
:::
operator beside the::
one. The::
would only bind a function to the value before it:would be equivalent to
The
:::
operator on the other hand would call the bound function in-place:would be equivalent to
The following would also work:
and would be equivalent to
And with
:::
:which would be equivalent to
So the two use-cases (which both occur frequently) would both be handled properly.