Hi, why do we choose `func` instead of `class` to ...
# compose
h
Hi, why do we choose
func
instead of
class
to create composable elements?
func
is lack of the capability of chain calls, for instance:
Text("...").font().textColor()
.
đź‘€ 5
a
Call chaining in a builder style for element properties is not necessary in kotlin functions since default/named arguments are available, and for compose in particular, decorators not specific to the particular composable can be constructed in this style and reused where desired in the form of modifiers. If you're asking about the emit style rather than returning a virtual dom of element definitions, it allows for stronger guarantees about who holds references to those objects, efficiency in the ability to optimize the underlying data structures as they are internal implementation details, and discourages inspection of the implementation details of an element subtree.
đź’Ż 7
Leland has gone into some of the advantages of Compose's model in various talks, I think this one had some additional details but he might link some others here as well:

https://www.youtube.com/watch?v=Q9MtlmmN4Q0â–ľ

m
https://raphlinus.github.io/ui/druid/2019/11/22/reactive-ui.html This is a really in-depth article, the idea is the "widgets" in Compose is not a class, but a trace of excecution (of functions)
👍 3
a
Raph worked with us on the Android toolkit team for a number of years in our text systems, he's great 🙂
h
Thank you so much for the clarification :)
👍 1
l
we had prototyped a
Component
class a long time ago which had a
compose
method. It would be similar to flutter widgets or react components. Eventually we decided to move away from it. The decision took into account a lot of different factors, some talked about above in the thread, but at a really high level one of the ways I looked at it was this: With a class based API, we were having to place “rules” and “constraints” on all kinds of different programming patterns that were not normal constraints that you would have… for instance, you couldn’t modify properties of the class yourself, you couldn’t hold on to a reference of the class, you couldn’t call its constructor, etc… This made compose feel less elegant and more like a “square peg in a round hole”. The decision could be looked at as a decision between “normal rules of functions, but the functions have extra capabilites” or “classes, but with a bunch of extra constraints/rules”. The former seemed strictly better to me, as it was additive. It also ends up being more ergonomic and fits closer with the mental model of how you should think about a composable widget etc. There are still some things that classes could have done better, but at the end of the day, I’m really happy with our decision here. It was also later validated more as react came out with react hooks and essentially declared functions as the preferred way of defining react components.
👍 2
a
yeah that was another layer of it for sure. Classes vs. functions and emit nodes vs. return nodes were two distinct decisions, but the implications fed into each other
a
A thing about classes, they define life cycles so elegantly than functions. But again functions capture the idea of a widget so well than a class could in so many ways. However I am in favor with the current approach to use functions instead of Classes. Widget classes have very weird rules
c
This video about the introduction of Hooks to React to solve a lot of the complications that came along with class based components historically is really good too

https://www.youtube.com/watch?v=dpw9EHDh2bMâ–ľ

Not strictly Android, but relevant to the general ideas behind Compose
f
HI all ! Sorry for popping this thread again. I want to ask you a question to see if my understanding is correct. Is it a too quick shortcut or not to say that Compose took the function approach (rather than the class approach like Flutter or React at the early stage before hooks if i'm right), thanks to Kotlin language's capabilities making this approach more readable (function default parameters and named parameters, kotlin DSL, and Lambda) ? Thanks for your help ! 🙂