-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bikeshedding syntax #10
Comments
I have slight reservations about the right hand side of the operator being a dynamic variable lookup in a syntax that doesn't look like it is. In property access and method calling in particular in order to achieve a dynamic lookup you have to enclose the expression via |
It is a bit atypical; it would be consistent, but unfortunate, if we were forced to only do |
@bmeck: Yeah, we could use an always-circumfix binary operator, like
obj~[fn](arg) // this-call
fn~(arg, ?) // PFA
obj~[fn]~(arg, ?) // PFA with a this-call 😄 |
The more I think about I’m planning to switch the operator from |
I definitely think using ~ would be confusing given PFA’s change to it. @js-choi maybe best not to so rapidly change the syntax of a proposal - i strongly prefer a dot/non-bracket mechanism, and i wouldn’t want ~ even if it’s a bracket mechanism and if PFA weren't using it, because it doesn’t convey any meaning about what it’s doing. |
Alright. We did get strong pushback about |
That concern seems like it would apply to any left-to-right syntax, including ::, and either way that’s worth discussing in plenary. I’m fine with switching back to |
We could also embrace the pipe-ness and use |
For the committee as a whole that could be true, but it's actually the specific symbol |
@rkirsling how is that different from " |
Hmm, I mean Anyway, I'm not specifically advocating for |
I'm confused about the apprehension, is all - are there specific languages that inform your expectation that it will be confusing? |
C++ uses // this pseudo code
Obj o = {};
o.foo; // regular access
Obj* p = &o;
p->foo; // same as `(*p).foo`, which is `o.foo` |
I suspect if we made an extensive list, literally any viable infix option will probably be used as property access in some other language. One question that guides my thinking here is: do we think more JS devs come from C++, or from PHP or Ruby? |
Admittedly, if it were just C/C++ then perhaps that wouldn't suffice for a strong objection, but I'm thinking of my own experience of needing to reluctantly edit a Perl script—I really wasn't expecting to encounter Are you suggesting that other choices would cause PHP/Ruby devs to worry about normal |
My understanding of your concern is, that based on expectations from C++ and Perl (and likely others), that To a PHP user, It seems to me that while we may disagree on "it will be confusing", that the two are in the same identical bucket - iow, either they're both confusing, or neither is. |
At any rate, I'm fine with someone calling |
C# also uses |
Note that |
After today’s ad-hoc meeting on dataflow proposals, I have edited this issue to focus on general syntax bikeshedding. There are three possible styles.
|
I dislike the I do like both of the other syntaxes, we just should ensure that they don't collide with the extension methods, pipeline, or decorator proposals. |
My preference of those three is definitely bind-this > call-this > this-arg; "this-arg" style feels very unjavascripty (it does feel slightly typescripty, which may be a pro to some but is a con to me) If we can find an operator for bind-this style that doesn't evoke confusion with "dot access" for some delegates, I would be pleased. |
I like call-this quite a bit and don't dislike the explicit- |
|
It would be pretty confusing to have |
@js-choi 's comment above about the precedence and |
With the |
Yeah, that one surprised me. Once I learned about it, I quickly got used to it, but it certainly doesn't look that's what would happen. I would have expected behavior that's more similar to await foo().bar()
// the same as
await (foo().bar()) |
The readme (which assumes tight unbracketed receiver-first syntax) talks about a similar problem; it has some early errors to deal with
|
@js-choi - I believe the comment about |
when it feels like it :) ( (no disagreement — just hadn’t appreciated till now how this could seem like one operator with “two precedences”.) |
Perhaps @varna is onto something though. I know there's a high bar for introducing new syntax into JavaScript, and there's been some worry about the number of different proposals that are coming through that can be considered related to flow control. Some syntaxes are more expensive than others. Some of the hesitation that comes with adding new syntax is:
If we can find a relatively concise and explanatory keyword form for this operator, perhaps this proposal would have a greater chance of success. Here's some options that goes along this avenue:
If we go this route, I would argue that we go back to having a loose precedence, maybe something akin to This option certainly has a number of upsides that the other options don't have. For example, this could perhaps resolve some of @rkirsling's concerns, without requiring us to use an operator that looks like a pipeline and yet behaves fairly differently from one. It is a bit more verbose, which is certainly a downside. However, perhaps it's worth asking ourselves how important it really is to be concise on this matter. The general sentiment I'm getting from the README and conversations is that the primary issue with Anyways, just another option to toss around. |
I am fine with a word operator (as an unbracketed receiver-first syntax) if other representatives are okay with one, but I would want it to have tight precedence, and I would want it to have short length. Let us not forget that If only word order were the determinant of readability, then the pipe operator alone would improve Having said that, maybe it’s possible to have a word operator that’s short enough to still be readable: input on fn(arg0)
input to fn(arg0) I wonder if there are any ASI hazards here, given that these aren’t keywords. |
There is an ASI hazard with all of them, but we'd probably use a NLTH ("no line terminator here") to avoid that. |
One more thing with a text operator is that it might look strange when mixing them with optional chaining: input.prop?.~>fn(arg0).prop
input.prop?.-.fn(arg0).prop
input.prop?.:fn(arg0).prop
input.prop?.:.fn(arg0).prop
input.prop?.::fn(arg0).prop
input.prop ?.on fn(arg0).prop
input.prop ?.to fn(arg0).prop |
Would "no line terminator here" work with multiline method chains though? value
.method()
to callExtension()
.otherMethod(); |
@bergus yes, it would likely be between the |
input.prop ?.to fn(arg0).prop This actually looks fine to me. At least, compared to the awkwardness of these sorts of things: x.fn?.(y)
x.value?.[y] (I found those to be really gross when they first came out. I was used to CoffeeScript's style which just had a question mark without a dot before I find this one to be a bit worse - this is just a dot soup 😆 input.prop?.:.fn(arg0).prop |
@theScottyJam The dot soup should actually be |
Ergonomics is the primary reason for my interest in this proposal. I would like to be able to convert a large amount of code that currently uses “topicalized” functions (unshifted receiver). This would eliminate the need for these extra functions (of which there are thousands). Much of this code suffers from the oops-I-accidentally-the-whole-lisp parentheses/ordering/readability problem that pipelines could also address, but pipelines would not alleviate the need for creating those topicalized variants and in any case, I am biased towards I’m sure there are other sigils that would get the job done with comparable clarity, but I’m describing a bit about my specific use case because I suspect many folks have different needs and so it may not be understood why some of us feel strongly about the need for concision and tight binding. Those things are the feature to me and I don’t think any of the alternatives I’ve seen actually solve my problems. If I were to naively convert the existing code in question to use We cannot upgrade |
Could you expound on this use case a bit more, maybe with something a bit more concrete. I'm not quite grasping the high-level picture you're trying to paint here. |
It’s code where nearly all intrinsic or host-provisioned method and accessor functions that are used anywhere at all are first captured and mapped to new functions with // A. it is currently
slice(toLowerCase(normalize(string)), 1); // <-- “backwards” + the “lisp parentheses” problem for a long “chain”
// B. but could be
string::normalize()::toLowerCase()::slice(1);
// C. just like in code with “perpetual” environmental assumptions
string.normalize().toLowerCase().slice(1);
// D. or the proposal could become a divine punishment for daring to dream of `::`’s triumphant homecoming 🥲
string calledAgainstBy normalize() calledAgainstBy toLowerCase() calledAgainstBy slice(1); In A, |
Sorry, but suggested word operators gave me shivers just seeing it :D I'm kind of feeling like it is better to not use a word operator at all if it as ambiguous as // I like this syntax
string::normalize()::toLowerCase()::slice(1);
// I'm kind of OK with this one...
string call normalize() call toLowerCase() call slice(1);
// but I'd rather write something like
string
call normalize()
call toLowerCase()
call slice(1);
// or this
string
::normalize()
::toLowerCase()
::slice(1); |
@varna I don’t think we were meant to like |
I do agree that we lose some value with generic words like But, perhaps because of the use case that @bathos brought up, a word operator really wouldn't be appropriate. |
Forgot to mention important fine print earlier: due to extremely incorrect priorities, there is a keyword available for use here that I would embrace without hesitation. |
I would prefer only use |
I don't like And such syntax actually make the call-this look like pipe. |
concerning |
Relevant, but E4X and JScript continue to have no impact on modern syntax choice. |
I would say that E4X and JScript have a slight impact on this proposal…in the same way that C, C++, Python, Ruby, Perl, and other languages that use Having said that, from a web-compatibility perspective, E4X and JScript indeed have almost certainly no impact. After all, there is no engine in existence that supports hypothetical programs simultaneously using both ES4 or JScript and ES2015+ syntaxes. |
Thanks, that’s much more precisely stated. |
2022-03 plenary bikeshedding slides
Possible criteria
Syntactic clarity
Would human readers often have difficulty with determining the syntax’s grouping?
Conciseness
Is the syntax significantly improve conciseness over the status quo?
Natural word order
Is the syntax’s word order more natural (e.g., subject.verb(object)) than the status quo?
Confusability with other JS features
Is there a risk of beginners and other developers confusing the syntax with regular dot property access?
Confusability with other languages
Is there a risk of developers confusing the syntax with visually similar syntaxes from other languages – especially if they have different semantics?
Overlap with other JavaScript features
Does the syntax greatly overlap with other features of the language?
(Note: A finding from the January post-plenary overflow meeting says, “In general, some overlap is okay, but too much is bad; we have to decide this on a case-by-case basis.”)
List of candidates
Receiver-first style (loose unbracketed)
This style was originally called “bind-this”, but we dropped function binding from it in 2022-03, so we renamed the style to “receiver first”.
Receiver-first style (tight bracketed)
This style was originally called “bind-this”, but we dropped function binding from it in 2022-03, so we renamed the style to “receiver first”.
Receiver-first style (bracketed)
Function-first style
This style was originally called “call-this”, but we are now calling it “function first” to distinguish it from receiver-first call-this. See the original explainer by @tabatkins.
This-argument style
First proposed by @rbuckton.
Original post
@rkirsling brought up in Matrix a few days ago the reasonable concern that
->
may still be confusing to beginners with.
.->
is a charged symbol. It has precedent as “method call” in Perl and PHP, but this proposal is for an operator that simply “changes the receiver of a function”, which is related but different.I’m not a huge fan of
::
, since that reads as “namespacing” to me, but I plan to tentatively switch back from->
to::
before the October plenary. There’s also~>
and~~
as possibilities. I don’t have any better ideas for its spelling right now.The text was updated successfully, but these errors were encountered: