[Proposal]: Inlined enumeration as function argument expression #4531
Replies: 8 comments 8 replies
-
IMO, this makes it painfully easy to miss the fact that an enumeration is happening and that the method is invoked multiple times. It's also very unclear what happens in the case of a fluent API, does the method get called on the return value or on the original target? If the latter it wouldn't work at all with immutable type builders. This feels like an awful lot of voodoo and for minimal savings. There's little appreciably different between: Register(Invert(foreach in locations)); and foreach (var loc in locations) Register(Invert(loc)); And it's much clearer how the latter will behave. |
Beta Was this translation helpful? Give feedback.
-
The presence of
It was specifically declared that the order of the nesting and chaining is taken into account. All examples provide the relation of the current vs the proposed syntax, without altering the result of the execution.
It might indeed appear cluttery, but personally, putting two lines of code in one is a bigger sin. I always ensure that I break the statement in the way they should normally appear like in the provided examples. |
Beta Was this translation helpful? Give feedback.
-
Which can easily be lost in the middle of a relatively long list of parameters.
That's a style preference. The language doesn't care if you put them on a single line or eight. But if your intent on breaking those two statements onto multiple lines is to make it more clear that the iteration is happening then you're very unlikely to want to use a |
Beta Was this translation helpful? Give feedback.
-
That's true, and it is not encouraged to be used in such cases. The motivation section explains the reason well enough, discarding the need to repeat it.
My intent is to oblige with the syntax and not convolute the line with all that information. In a standard simple This new syntax gets rid of the declaration and naming of a temporary variable that holds the enumerated element. The produced result only consists of the action, the indication of an enumeration process and the enumerated collection. It's also flexible enough to allow other arguments to exist in the call, without invalidating the syntax in the case of a function that has more than 1 arguments. |
Beta Was this translation helpful? Give feedback.
-
What about |
Beta Was this translation helpful? Give feedback.
-
LINQ does provide a |
Beta Was this translation helpful? Give feedback.
-
I don't see the benefit here. All it seems to save is not writing the |
Beta Was this translation helpful? Give feedback.
-
foreach (var c in chars)
stringBuilder.Append(c).Append(' '); stringBuilder.Append(foreach in chars).Append(' '); First can't become second as there is a difference in logic. At least as I see it. First one adds a space for every iteration, second one doesn't. Seems like your new syntax could trick even yourself :) (or me) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Inlined enumeration as function argument expression
Summary
This syntax should provide a faster way to call a function for each element in an enumerable object.
Motivation
The main motive behind this syntax is simplifying the code that is required to properly enumerate through a collection of objects and only call one function within. In other words, this aims to simplify the process of performing a single operation on a collection of objects.
Detailed design
Assuming that an operation is performed like so:
the new syntax simplifies this code into:
This skips the need for introducing a temporary variable into the mix, as its only purpose is to be used once.
For functions with multiple arguments, the
foreach in
statement should be placed before the collection whose iterated elements are intended to be used as an argument at the desired position. For instance:becomes:
Multiple
foreach in
can be allowed per single function call, but it becomes the equivalent of nesting eachforeach
loop in each other. Example:becomes:
Multiple
foreach in
can also be present inparams
args. Example:becomes:
Nested and chained function call expressions are also supported.
An example of a chained function call expression:
becomes:
And an example of a nested function call expression:
becomes:
There is also the ability to apply this for
IAsyncEnumerable
objects, by using theawait foreach in
variant. Example:becomes:
Drawbacks
This syntax does not break compatibility with other rules. It is however a relatively niche feature, and despite it not requiring changes outside Roslyn itself, it could not prove worthy of existing.
One issue is from supporting multiple
foreach in
in a single call, which may increase line size for cases when more than 2 are used, sacficing code readability.Alternatives
Another proposed design is only offering a shorthand for:
into:
Same conditionals apply, but this syntax only works for functions that take exactly one argument. It is not clear if nested or chained function call expressions can be supported, or what new features and syntax would have to be introduced for that to work.
Unresolved questions
None yet.
Design meetings
None.
Beta Was this translation helpful? Give feedback.
All reactions