-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Unnecessary parentheses in function calls. #1407
Comments
What compilation would you recommend for What about this common use case for jQuery? What would the whitespace do here?
|
So you're suggesting a function call's argument list ends when it sees a dot-style property access but only when there's whitespace before the dot (which, I'll remind you, is just JS)?
I can kind of see why someone might want to write that the first way (DSLs maybe?), but it is quite a bit more readable with explicit parentheses. -1 for now. |
erisdiscord, i think EDIT: now that i think of it, |
michaelficarra, yes, but JS is ugly. ;) I agree that the second example is cleaner and I hope that no one writes the code in real life with as many parameters without parenthesis. But the point is not to allow long lists of parameters without parenthesis (as long as there's a clear logic on how they would compile if someone wrote them), but to allow cleaner code in simpler examples. |
Interesting. There would be enough visual hint since you don't usually space before |
👍
compiles to
and
compiles to
(good luck if you don't like fixed-width fonts :P ) |
@thejh that's horrifying. |
@erisdiscord I'd rather call it "consistent". |
Humm... on a related note, what would you think about doing operator precedence using spaces? Something like
|
@thejh I call it "pretty difficult to read". I'm not really a fan of the original proposal and I can't see this version bringing any additional value. -1 :C |
@thejh, why would it make a difference if there's one or two spaces before dot (.)? As i see it, with this proposal |
@thejh, on the operator precedence: i like it. :) Haven't given it that much thought, though. |
To return to the jQuery example presented by @erisdiscord:
Would work just as it now does, but with the new rules you could actually write it without the parenthesis:
Which isn't possible in CoffeeScript at the moment. The only problem would arrive if you would add another function before $:
Because in this case the .button() would be executed on |
It gets really unreadable after a few methods. Consider this:
It would be written as
You just borked the function expression. This could be the case for a custom operator, we don't have many options since
But it doesn't make things much better, besides being a huge departure from "normal" syntax. |
One that is kind of ok is re-using
This would be different from For clarity the dot could be kept: |
Only because you mixed implicit indentation (inserted after |
@satyr but that kind of defeats the purpose of not having to nest things in parenthesis. |
"Significant whitespace" speaks primarily about significant linebreaks and significant indentation. These are readable. Not all whitespace should be significant. Some types of whitespace should not be significant: such as the whitespace within a line. |
Already significant beyond help:
|
Yeah, we are pretty big on the significant whitespace here. Still, this one's a bit of a stretch. I could live with it, but it's nowhere near as intuitive or readable as our other instances of significant whitespace. |
I agree that binding the property after the dot notation to the first function in the command line (or the one after the previous dot notation) allows you to write code that is hard to read. But there's no programming language that can stop people from writing bad code. So i guess my question is this: is there ever a time when someone would write
...I actually find it much more logical that .button() would bind to another_func:tion, since this allows us to process the whole function line at once, and only after that move to the next lines. Currently it's slightly backwards since you first have to process $('a') in your head, then .button(), then .click(...) and only then jumping all the way back to another_func. |
Yep, CoffeeScript has intra-line significant whitespace. But maybe it's a good idea not to increase the quantity of it, especially by adding an easily confusable and barely debuggable significance of whitespace affecting the order of operations. |
Actually, while I am not too keen on
Is it reasonable for a newline to close the outermost implicit parentheses in this case? |
This came up on Stack Overflow recently. It would mean that you could write
which is pretty nice. And people have long been begging for
to be supported somehow. The main counterargument Jeremy and others have expressed toward such proposals is that they overload indentation with multiple meanings. This proposal, on the other hand, makes the indentation non-significant, the same way that
is a perfectly acceptable way of writing Let's remember that "it allows ugly code" isn't a compelling argument against a language feature—ugly code will always be possible. The question is, rather, "Does it encourage ugly code?" And this proposal, in my view, does the opposite, allowing more stylistically consistent code to be written. An enthusiastic +1 from me. |
I would really, really like this to happen. There isn't a great reason to write |
I wanted to propose why this issue is more in line with CoffeeScript's philsophy by preserving significant whitespace. Right now, CoffeeScript is less ambiguous in one way because it converts
into
where the Depending on how #1495 is resolved, this definition may not extend to nested chaining syntaxes (though parentheses could still be omitted); but one possibility to get the current behavior is to make greater indentation override the implicit parentheses:
Compile to |
OP @jussiry, +1 I just wanted to add the main Benefit of supporting this feature, is to not have to go backwards into your code, to have to add parenthesis to do something simple. js: coffee: ... have to go backwards and add parenthesis
|
I'm pretty new to using CS, but wished for quangv's syntax almost immediately. I've been writing a great deal of jQuery and Jasmine specs. Just yesterday I found myself writing something like this 50+ times:
`````` expect($('#id').attr('foo')).toBeUndefined()``` But that's just JS. What I wanted to write was:
CS is a distinct language of it's own, so arguments concerning what JS programmers expect shouldn't be relevant. Inline whitespace already has semantics (removing parens ;) Is there a reason parenthesis couldn't be restricted to enforcing precedence and allow a single space to replace the use of parenthesis for function calls? I don't see why you couldn't even write this:
It's not like I can have BOTH a property on an object AND a method that both have the same name. As for this syntax encouraging the writing of bad code, more helpful compiler errors and a CoffeeScript version of lint would certainly help with that. As others have already said, you can't stop people from writing bad code. If they want to write clever code, it's going to be difficult to read and debug. I agree with quangv wholeheartedly. Going back to add those parens is a pain in a language that (in my limited experience) tries to eliminate as much pain as practical. Has anyone seen a pull request for this one?
|
@gijohnson-usgs, what is this supposed to do? It could be Quite ambiguous :( |
If this was added, the compiler should just read it left to right and assume no nesting unless parens indicate it.
For the jasmine example, parens are definitely needed, there's no way around it |
I think maybe for nesting, parentheses should still be used, so the above should be written
and
|
@renekooi, you're right. That IS ambiguous. I've been thinking about this and the problem is nested function calls:
I've been thinking about this for a couple of days and I think I came up with a solution (don't know if anyone else would like it). If " .a" closes a function call before accessing the a property or invoking a function, then you could have:
taking this a step further and thinking of " ." as generically closing the the previous function call you have:
now that turns into quite a bit of whitespace, and I'm not sure how often people would use this, but shorthand could be:
each additional "." denotes closing another paren. If it's common to desire closing all of the nested function calls, you could use "!.":
The "!" is an exclamation in english and can intuitively thought of as "close ALL of those parens!". In that case, I could write my original example as:
Let me know if I overlooked anything again. |
@gijohnson-usgs, interesting thinking, but starts to get pretty complex. I'v stated this before, but I think the cleanest way would be to just interpret 'space dot method' the same way you are suggesting exclamation mark to be used. This would allow us to do clean chaining, e.g.
Anything more complex than that, and you'll most likely want to use parens for easy reading anyway. |
@jussiry, it does start to get complex. And nesting that many function calls would likely make for quite unreadable code anyway (there are reasons we use variables). The only way to know for sure is to try it out. Don't know when I'll have time to go through my code to find examples of deeply nested function calls. If I found them, it'd prbly be a good time to refactor anyway. However, the jQuery I'm writing at the moment could definitely benefit from you're example. |
agreed +1 |
This is all pretty interesting, but looking at the one sensible chaining case, is @quangv's sample really any worse just written out as:
Personally, I find that a lot easier to parse visually, which is the whole point, right? Human friendly code? |
Some people reason code faster with parenthesis and some without, depending on what kind code they are used to reading. In this example, i would definitely write |
Unlike other superfluous punctuation (yes, I'm talking about you, semicolon), parentheses have a high signal-to-noise ratio. They connote perfectly and fairly succinctly the developer's intent. Paren-free syntax is a fad. I'm against this proposal (for hopefully obvious reasons). Parentheses generally help readability. There are certainly cases where you can obviously infer them like in this parenthetical statement, but I digress but it is silly to bend over backward to avoid them. |
@showell I agree that doing all you can to avoid parenthesis is a very bad idea. But then again there are cases where leave them away helps to keep code cleaner without making it harder to reason with (e.g. chaining with row changes). So yes, with this addition you could write code that is ugly and hard to reason with, but unfortunately that's possible in every programming language that exists anyway, so i don't see that as good argument against this addition. |
@jussiry I'm not sure I understand your "that's possible in every programming language that exists" comment. Some languages enforce explicit parentheses more than others. Python is more strict about parentheses than Ruby, for example. The tradeoffs are obvious enough. Python code is easier to reason about than Ruby (no need to guess about where the parentheses would be), but it's also more visually cluttered (due to the parentheses). All I can tell you is that Python is more pleasant to read than Ruby. It's easy to ignore parentheses when they're just visual clutter; it's much harder to infer grouping when parentheses are omitted. I'm not advocating for CS to completely abandon paren-free syntax. It makes a fairly nice tradeoff now. I'm just saying enough is enough. |
@showell Fair point. I guess I'm leaning more into the camp that wants to give programmers the right to choose how they want to write their code, but if I were in a position where I'd have to read lots of code written by less-than-expert programmers I'd probably also prefer more stricter rules. |
@jussiry There's definitely a tension between strictness/predictability and artistic freedom. In the early stages of developing a programming language, I would err on the side of strictness. It's always easier to loosen up a language than tighten it down (because of backward compatibility concerns). I would argue that CoffeeScript, while promising and beautiful, is still in the very early stages of development. For godsake, it doesn't even have line mapping support. |
Good points. I guess it depends on what the Philosophy of CoffeeScript,
I'd assume readability is one of the philosophy of CoffeeScript as well... @showell, good points about Python vs Ruby... I'd go with Python 110% !!! I use to be one of the proponents of no parentheses... but if it goes against the Philosophy of CoffeeScript, then I am against it. @showell when you say line mapping support you mean the debugging error messages? |
@quangv I think the Philosophy of CoffeeScript can have many interpretations, so I wouldn't go so far as to say that no-parens goes against it. It's really just my own opinion. By line-mapping support, I specifically mean that the compiler doesn't emit line number mappings, but, yes, one of the consequences of that omission is that debugging error messages are JS only. |
I'm way late to this party, but just spent a long time reading through this and a few of the other big related threads. Very interesting points on all sides. Mostly though, it's so great to see civil and respectful discussion. Thanks guys -- what a great community. I just wanted to toss in a +1 to support chaining on newlines -- so useful for jQuery. That's what it boils down to for me -- it seems this is possible to support and worth it given that jQuery is such a popular use case. Pragmatic and effective. |
just wanted to add... disdain of parenthesis could be reduced by using the
|
@quangv Sure, but that just adds a trailing |
@mcmire I find myself writing |
Another problem of this is when you are using promises.
will compile to
instead of
which has led me to a lot of unintended behaviour and a lot of extra parentheses. |
Note the leading dot syntax on a new line is on master now (via #3263). To the discussion here I will only add that the semantics we use are: a b c
.d
.e compiles to |
I think we got what we wanted :-). |
Currently
foo bar .baz()
compiles tofoo(bar.baz());
This seems unlogical, since the same result can be gained with cleaner code by writing
foo bar.baz()
.So should't it rather compile to
foo(bar).baz();
? This would allow us to write code with even less parenthesis in many situations (something i'v really learned to love with CoffeeScript).The text was updated successfully, but these errors were encountered: