Skip to content
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

Statement vs expression in => fat arrow explanation #4582

Closed
suragch opened this issue Feb 7, 2023 · 2 comments · Fixed by #5854
Closed

Statement vs expression in => fat arrow explanation #4582

suragch opened this issue Feb 7, 2023 · 2 comments · Fixed by #5854
Assignees
Labels
a.language Relates to the Dart language tour e1-hours Can complete in < 8 hours of normal, not dedicated, work p2-medium Necessary but not urgent concern. Resolve when possible. st.triage.ltw Indicates Lead Tech Writer has triaged

Comments

@suragch
Copy link

suragch commented Feb 7, 2023

Page URL

https://dart.dev/language/functions

Page source

https://github.com/dart-lang/site-www/tree/main/src/language/functions.md

Describe the problem

The docs in the linked page state:

Note: Only an expression—not a statement—can appear between the arrow (=>) and the semicolon (;). For example, you can’t put an if statement there, but you can use a conditional expression.

In describing what a statement is in this Stack Overflow answer, I listed some examples of statements, including the following:

  • myInt = 1;
  • print('hello');
  • return null;
  • if (name != null) { return name; } else { return 'Guest'; }

One reader commented:

I found example contradictory to myInt = 1; being statement. It's lambda() => myInt = 1;. Why? Look at fat arrow explanation in the docs: dart.dev/guides/language/language-tour#functions. It says "Only an expression—not a statement—can appear between the arrow (=>) and the semicolon (;)". The aforementioned example compiles, linter doesn't complain, so it's an expression, not a statement.

That's true:

void main() {
  int i = 1;
  final function1 = () => i = 3;
  final function2 = () => print(i);
  function1();
  function2(); // 3
}

Am I wrong in my understanding of what a statement is? Is i = 3 an expression rather than a statement? Is print(i) not a statement?

Or is the documentation misleading?

Expected fix

If I'm wrong about what a statement is, then nothing needs to be changed about the documentation note above. However, we should define the terms statement and expression somewhere within the docs since these terms are used liberally without a clear explanation.

If i = 3 and print(i) are in fact statements, then we should refine the => fat arrow note in the docs. I'm not exactly sure what that better wording would look like, though.

Additional context

No response

@danagbemava-nc danagbemava-nc added st.triage.triage-team Triage team reviewing and categorizing the issue a.language Relates to the Dart language tour p2-medium Necessary but not urgent concern. Resolve when possible. e1-hours Can complete in < 8 hours of normal, not dedicated, work and removed st.triage.triage-team Triage team reviewing and categorizing the issue labels Feb 7, 2023
@atsansone atsansone added the st.triage.ltw Indicates Lead Tech Writer has triaged label May 3, 2023
@atsansone atsansone self-assigned this May 15, 2024
@lrhn
Copy link
Member

lrhn commented May 23, 2024

I think the examples are fine. They are statements when used as statements.

It says "Only an expression—not a statement—can appear between the arrow (=>) and the semicolon (;)".

Correct, myInt = 1 is an expression, and myInt = 1; (expression + ;) is an expression statement.

Ditto for i = 3 and print(i), which are both expressions, where i = 3; and print(i); are statements.
Where a statement is expected, most expressions can be followed by ; to produce statements.

You're not saying this, but I'll address it anyway: That myInt = 1;, including the semicolon, occurs in lambda() => myInt = 1; doesn't mean that there it is a statement there. It's not parsed as a statement, the ; doesn't bind to the myInt = 1 like it would in an expression statement.

Whether a sequence of characters/tokens is a statement or not also depends on the context they're parsed in, because that decides what they're parsed as.

The examples here are of code that are statments when they're used as statements, if you use them where a statement is expected and allowed. And if you use them anywhere else, one shouldn't be surprised that they're not statements in a place where statements cannot exist to begin with.

Or stated differently, if myVar = 1; is parsed as a unit, with the ; applying only to the myVar = 1, then it is (most likely, unless I've forgotten some corner case) a statement.

If you plug the same sequence of characters into a different context, then it parses differently, and usually the ; applies to something else.

  • void main() { myInt = 1; } - myInt = 1 is an expression, myInt = 1; (with the ;) is an expression statement.
  • lambda() => myInt = 1; - myInt = 1 is an expression, the following ; ends the function declaration.
  • class C { int myInt; C() : myInt = 1; }. The myInt = 1 is a variable initializer in the constructor initializer list. The following ; ends the initializer list and constructor.
  • var myInt = 1; - The leading var completely changes the meaning, from an assignment to a declaration. The ; ends the entire declaration.

In the last three cases, the myInt = 1; were not parsed as a unit, the ; applied to more than just myInt = 1, and the myInt = 1;, by itself, is not an statement.

atsansone added a commit that referenced this issue May 24, 2024
@suragch
Copy link
Author

suragch commented May 27, 2024

@lrhn Thank you for your thorough explanation!

atsansone added a commit to atsansone/site-www that referenced this issue May 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a.language Relates to the Dart language tour e1-hours Can complete in < 8 hours of normal, not dedicated, work p2-medium Necessary but not urgent concern. Resolve when possible. st.triage.ltw Indicates Lead Tech Writer has triaged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants