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

Proposal: Sequence Expressions #6182

Closed
gafter opened this issue Oct 20, 2015 · 18 comments
Closed

Proposal: Sequence Expressions #6182

gafter opened this issue Oct 20, 2015 · 18 comments

Comments

@gafter
Copy link
Member

gafter commented Oct 20, 2015

We propose a form of expression that allows you to declare temporary variables before the final result of the expression. We replace the existing parenthesized expression with the following

parenthesized-expression:
    ( sequence-statementsopt expression )
sequence-statements:
    sequence-statement sequence-statements
    sequence-statement
sequence-statement:
    expression-statement
    declaration-statement

The scope of any variable declared in a parenthesized-expression is the body of that parenthesized-expression.

The type of a parenthesized-expression is the type of its final expression.

At run-time the statements are executed in sequence, and then the final expression is evaluated, which becomes the value of the whole sequence expression.

The definite assignment and reachability rules need to be specified, but they are trivial.

This is particularly useful in combination with the expression form of the pattern matching construct #5154.

/cc @TyOverby

@alrz
Copy link
Contributor

alrz commented Oct 20, 2015

love this 👍

@orthoxerox
Copy link
Contributor

Why not

parenthesized-expression:
    { sequence-statementsopt expression-statement }
sequence-statements:
    sequence-statement sequence-statements
    sequence-statement
sequence-statement:
    expression-statement
    declaration-statement

?

@alrz
Copy link
Contributor

alrz commented Oct 20, 2015

@orthoxerox it will be ambiguous in expression-bodied lambdas (discussed at length in #5402).

@gafter
Copy link
Member Author

gafter commented Oct 20, 2015

@orthoxerox Because that would break compatibility by making (1+1) a syntax error for two reasons - first, because 1+1 is not one of the expression forms allowed as an expression-statement, and second, because it lacks the semicolon that is part of an expression-statement.

Oh, wait, you're suggesting that we replace the parens in a parenthesized expression with curly braces? I think that would make lots of things ambiguous.

@paulomorgado
Copy link

Why is it named sequence?

@gafter
Copy link
Member Author

gafter commented Oct 21, 2015

@paulomorgado Because it evaluates the expressions sequentially for side effects. Got a better name?

@paulomorgado
Copy link

@gafter, this used to be referred as declaration expressions, right.

Aren't you afraid it might be confused with "as opposed to asynchronous expressions"?

And, no! I don't have a better name. Yet!

@ufcpp
Copy link
Contributor

ufcpp commented Oct 21, 2015

What is its result type? That of the last expression? I receive the impression from the name "sequence expression" that its result type is an array of each expression.

@gafter
Copy link
Member Author

gafter commented Oct 21, 2015

@paulomorgado No, this is not the same as declaration expressions. That was where you could declare a variable at its first use, something like M(int x = 12, x*x).

The type and value is the type and value of the last expression.

@paulomorgado
Copy link

See?

@gafter
Copy link
Member Author

gafter commented Oct 22, 2015

@paulomorgado I'm not sure you understand. This would not be legal under this proposal:

M(int x = 12, x*x)

That's because a local declaration (with or without its semicolon, which is normally part of its syntax) is not an expression. If you wanted to do something like that with this proposal, you'd have to write

(int x = 12; M(x, x*x))

@paulomorgado
Copy link

OK! Got it, @gafter!

My "See?" comment was regarding this:

@paulomorgado:

Aren't you afraid it might be confused with "as opposed to asynchronous expressions"?

and this:
@ufcpp

I receive the impression from the name "sequence expression" that its result type is an array of each expression.

But given your last example, sequence is starting to make sense to me.

@TyOverby
Copy link
Contributor

@gafter Since you invited the bikeshedding, I think "chained expressions" would be a nice name. It doesn't have the connotation of sounding like a list or a generator, and the "chain" imagery helps show that expressions can depend on results produced by previous ones.

@quinmars
Copy link

FYI, gcc calls a similar C extension "statement expression".

@gafter gafter removed their assignment Nov 21, 2015
@gafter gafter removed this from the C# 7 and VB 15 milestone Nov 21, 2015
@qrli
Copy link

qrli commented Dec 18, 2015

Seems it will introduce a little inconsistency with the for statement, which uses comma.
Ugly code:

for (int i = 0, j = 1; (int k = i + j; M(k, k)); i++, j *= 2)
{
}

Though people won't mix them in practice.

It will also be possible to write silly program like this, which does not look like C#:

public double Foo() => (
   int a = GetSomething();
   Log(a);
   DoSomething(a);
);

@leppie
Copy link
Contributor

leppie commented Mar 24, 2016

Sub

@alrz
Copy link
Contributor

alrz commented Dec 5, 2016

The scope of any variable declared in a parenthesized-expression is the body of that parenthesized-expression.

This conflicts with current scoping of is var and out var

var x = (e is T t ? t : foo);
// t is in scope!

Probably this should be decided now if this feature is planned for a future release.

@gafter
Copy link
Member Author

gafter commented Mar 28, 2017

Issue moved to dotnet/csharplang #377 via ZenHub

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants