Adam Powell
10/04/2019, 8:25 PMText(text = "Hello, world!", modifier = padding(16.dp))
kioba
10/06/2019, 10:56 AMText(text = "Hello, world!")
.padding(16.dp)
and they are easy to create:
(@Compose () -> Unit).padding(all: Dp) = ...
Adam Powell
10/06/2019, 2:50 PMUnit
, not its own function type. Compose deliberately doesn't construct a virtual dom-like structure via returns, and it comes back to still needing to know whether a composable function emitted zero, one or more layout node children. Plus it implies that you have to read nesting from the inside out, and that these builder calls would need to come after potentially large blocks of content. The type of the container and its modifiers (which can be seen as arguments/parameters/attributes) are visually and semantically split from one another in this style.flow {}
builder family has a similar property where operators at the end look a little strange when formatted by standard kotlin formatters: val f = flow {
// a couple dozen lines of code...
}
.fooOperator {
// Some code here
}
.someOtherOperator(params)
but flows express data that starts at the visual top of this code where you begin reading and is transformed at each step as you read down. Compose UIs express a tree where the shape itself is more relevant when read as a preorder traversal; the function names and parameters appearing before trailing child lambda blocks already imply this kind of preorder reading. The trailing builder style means reading some of the code as a postorder traversal and mixing the two seems harder to read.kioba
10/06/2019, 4:35 PMUnit
can be changed any time to return a proper type, it is just the decision which is hard to change. Wrapping calls into lambda is the suggestion if someone is looking for lazy evaluation and Compiler plugin could wrap any @Compose function into a lazy lambda to return that because the compliler can detect if the expression is over and can analyze it.
Text(text="Hello")
<- just execute
Text(text="Hello").padding(16.dp)
<- wrap Text in a lamda return it and execute padding before the lambda. If someone wants to write similar extension, they could extend the Compose
type which is nothing more than typealias Compose = () -> Unit
aka the wrap.
It doesn’t have to be the dom system but the order it executes.modifier
is mixing the two because it is showing up at the end of the text widget. It doesn’t matter if it is a trailing function call or the last argument as “modifier”. both of these are hard to read due to the postorder
as you described. It also forces all the widgets to have a modifier
arguments which is just makes the whole tree unreadable.
I haven’t checked out the latest compose, but I am worried that Modifiers are hardly composable. It feels like “take it as it is” or build your own style which reminds me to the existing way of dealing with view styles on Android. I really hope it is not true and I am mistaken.Style(modifier = padding(16.dp)) {
Text(text = "Hello World!")
}