You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a request for improved support in Dart for working with anonymous objects.
We already have the ability to work on anonymous objects in Dart, to some extent. In particular, we can use constructs like "Hello, world!".substring(0,5).toUpperCase() to perform a single operation on an object that has no name (here, it's the result of evaluating the string literal, but it could be any expression), and then perform an operation on the returned result (here: "Hello"), etc.
It gets more inconvenient if we wish to perform more than a single operation on the same anonymous object. Let's consider a few examples where that issue is addressed in different ways.
This code has been written carefully in order to achieve a certain balance between conciseness and readability.
Note that we have several declarations (paragraphBuilder, paragraph, and sceneBuilder) that are only used once. This may be taken as a hint that the declarations could have been omitted, and the initializing expression for each of them could have been moved to that single location where the declared name is used.
So this is an example where an object is given a name, such that we can avoid to do just that. It is discussed below (version 3) why one might prefer to do it this way. But let's first consider the ways in which this example already works on anonymous objects.
Unfolding the Example
The code in version 1 already contains one construct which could be considered to be a response to this very issue, namely cascades: They allow us to perform several operations on an anonymous object. So we could unfold the example above to omit cascades:
This transformation yields simpler declarations, but it introduces some statements. This means that the resulting code is "less declarative", and it may be harder to reason about because the reader will have to discover that there is no non-trivial control flow.
The other difference is of course that the names paragraphBuilder, paragraph, and sceneBuilder are now used several times. We now have more text and more redundancy, and that makes it harder for a developer who is reading the code to get the big picture.
This is the kind of motivation that we have for introducing cascades in the first place. So why don't we just go all the way?
Folding the Example
We could go in the opposite direction and eliminate all the single-use declarations. In other words, we tried to unfold the example and saw some problems, but we could also fold it:
The resulting code is more concise than version 1 and 2, and it stands out that we are performing a drawParagraph operation and a render operation.
However, the arguments to those two method calls are rather complex, and it's likely that a reader of this code would get an incorrect understanding of how many objects we are actually working on, which type each of them has, and what each of those operations is doing. Also, it won't help if the indentation is inconsistent.
Finally, a person who is writing this kind of code might easily put too many or too few parentheses here and there, so the writing process is basically subject to the same difficulties as the reading process, plus some steroids.
Situation
Dart seems to have an already decent amount of support for working on anonymous objects, but developers will easily get into some difficult trade-offs: We could use more complex expressions, or we could introduce more declarations, and there might be a sweet spot somewhere in the middle.
On top of that, it should be noted that we can only express a linear sequence of operations with a cascade (do this, then do that, just like a plain sequence of statements S1; S2; S3;). So if we do wish to use any non-trivial types of control flow (say, a loop) then we're lost: We will have to unfold, and use regular statements.
This issue is a request for more flexibility in this area.
The text was updated successfully, but these errors were encountered:
This is a request for improved support in Dart for working with anonymous objects.
We already have the ability to work on anonymous objects in Dart, to some extent. In particular, we can use constructs like
"Hello, world!".substring(0,5).toUpperCase()
to perform a single operation on an object that has no name (here, it's the result of evaluating the string literal, but it could be any expression), and then perform an operation on the returned result (here:"Hello"
), etc.It gets more inconvenient if we wish to perform more than a single operation on the same anonymous object. Let's consider a few examples where that issue is addressed in different ways.
An Example
Consider this excerpt from the Flutter raw 'hello_world.dart':
This code has been written carefully in order to achieve a certain balance between conciseness and readability.
Note that we have several declarations (
paragraphBuilder
,paragraph
, andsceneBuilder
) that are only used once. This may be taken as a hint that the declarations could have been omitted, and the initializing expression for each of them could have been moved to that single location where the declared name is used.So this is an example where an object is given a name, such that we can avoid to do just that. It is discussed below (version 3) why one might prefer to do it this way. But let's first consider the ways in which this example already works on anonymous objects.
Unfolding the Example
The code in version 1 already contains one construct which could be considered to be a response to this very issue, namely cascades: They allow us to perform several operations on an anonymous object. So we could unfold the example above to omit cascades:
This transformation yields simpler declarations, but it introduces some statements. This means that the resulting code is "less declarative", and it may be harder to reason about because the reader will have to discover that there is no non-trivial control flow.
The other difference is of course that the names
paragraphBuilder
,paragraph
, andsceneBuilder
are now used several times. We now have more text and more redundancy, and that makes it harder for a developer who is reading the code to get the big picture.This is the kind of motivation that we have for introducing cascades in the first place. So why don't we just go all the way?
Folding the Example
We could go in the opposite direction and eliminate all the single-use declarations. In other words, we tried to unfold the example and saw some problems, but we could also fold it:
The resulting code is more concise than version 1 and 2, and it stands out that we are performing a
drawParagraph
operation and arender
operation.However, the arguments to those two method calls are rather complex, and it's likely that a reader of this code would get an incorrect understanding of how many objects we are actually working on, which type each of them has, and what each of those operations is doing. Also, it won't help if the indentation is inconsistent.
Finally, a person who is writing this kind of code might easily put too many or too few parentheses here and there, so the writing process is basically subject to the same difficulties as the reading process, plus some steroids.
Situation
Dart seems to have an already decent amount of support for working on anonymous objects, but developers will easily get into some difficult trade-offs: We could use more complex expressions, or we could introduce more declarations, and there might be a sweet spot somewhere in the middle.
On top of that, it should be noted that we can only express a linear sequence of operations with a cascade (do this, then do that, just like a plain sequence of statements
S1; S2; S3;
). So if we do wish to use any non-trivial types of control flow (say, a loop) then we're lost: We will have to unfold, and use regular statements.This issue is a request for more flexibility in this area.
The text was updated successfully, but these errors were encountered: