also can Compose be used in a scriptable way? sim...
# compose
k
also can Compose be used in a scriptable way? similar to View's programmable api
Copy code
fun onAdd(v: ViewGroup, child: View) {
    v.addView(child);
}
but for Composables instead
j
The whole purpose of compose is to be declarative instead of imperative. So you would be fighting yourself here
In compose you just do for example
Copy code
Column {
    Composable1()
    Composable2()
}
t
Create a state that you can imperatively modify and then build your ui declaratively based on the latest current state
k
so for example, language bindings CANNOT be created for compose to construct composables in said language?
j
what do you mean android bindings?
k
eg, python, lua, ruby, ect
j
nope, compose is stricly kotlin technology
since it relies on multiple kotlin constructs and the most important - kotlin compiler plugin
k
hmm
j
you could generate kotlin code in other languages and then compile it, but.. why 😄
for now (and i doubt it will ever change) you can only write compose ui in kotlin
k
could a function return a composable?
eg
Copy code
fun retText(s: String): Text {
    return Text(text: s)
}
j
i'm not sure if it's possible but this seems like hard antipattern
k
damn
f
could a function return a composable?
eg
```fun retText(s: String): Text {
return Text(text: s)
}```
"Composable" is not an object - it's a function. So you could do
Copy code
fun retText(s: String): @Composable () -> Unit = @Composable { Text(s) }
k
oh ok
Copy code
fun retText(s: String): @Composable () -> Unit = @Composable { Text(s) }

fun retBox(): @Composable () -> Unit = @Composable { Box() }

fun addTextToBox(box: @Composable () -> Unit, box: @Composable () -> Unit): @Composable () -> Unit = @Composable { box(); text(); }
could we do something like this?
j
while that should work i don't know how the kotlin compiler can build recomposition avoidance around that
the function will return new composable at each recomposition
k
tho i have no idea if it is possible to actually add said text to said box as if
Copy code
Box {
    Text(s)
}
f
It would be better to give as a hint of what exactly you are trying to do. What is the end-goal
k
basically i want to create a scriptable UI
f
What does that mean? 😄
j
ok, i think you mean something like generating ui from json?
k
like...
Copy code
val box = box()
val text = text("hello")
box.add(text)
display(box) // displays the constructed [box] object in compose kotlin
f
Yeah, I would answer the same Jakub did 😄
The whole purpose of compose is to be declarative instead of imperative. So you would be fighting yourself here
j
this seems like just fighting the declarative ui
why 😄
i understand json defined views for something like lists (https://medium.com/mobile-app-development-publication/jetpack-compose-enables-json-defined-view-layout-b1f8a0d5df8c), but why would you do imperative scripting over declarative framework?
k
because Android google play store disallows loading of pre-compiled android resources (eg, JAR, AAR, DEX) from internet i assume this also includes (.kotlin/.java files to compile)/.class files to load
j
look at the link i send - this is the best you can get
but doing whole ui, with nesting and so on - i don't think you can do that in performant way
and this all seems so unnecessary, why go native if you want to have fully online declared ui? Just embed WebView and you don't have to reinvent the wheel
the performance will be probably even better this way
k
because such will be downloaded by the user and then stored locally to load up at any time
j
You can (and should) cache html
that's not my point
you want to reinvent online scripting language
and it exists
k
would web compose be as fast as jvm compose
assuming all files are stored locally
and would such require an active internet connection
j
look, creating all composables dynamically like you wanted to basically destroys all optimizations that compose offers. Not to mention - what about state? How do you want to handle that?
compose web is just a front-end framework, like any other
it would be probably faster than this "dynamic native compose" you think about
i just don't see your idea as feasible, both in state management and performance ways
k
alright
google play only allows downloading and execution of javascript for web browser applications, right?
eg https://www.theregister.com/2021/07/29/google_play_python_javascript/
Starting October 15, 2021, Google said, "We're clarifying the Device and Network Abuse policy to prohibit apps or SDKs with interpreted languages (e.g., JavaScript) loaded at run time from violating any Google Play policies."
action against apps that "interfere with, disrupt, damage, or access in an unauthorized manner the user's device, other devices or computers, servers, networks, application programming interfaces (APIs), or services."
Fetching executable code from sources other than Google Play is also disallowed, except for code running in a virtual machine that has limited access to Android APIs, like JavaScript running in a WebView or browser.
specifically https://support.google.com/googleplay/android-developer/answer/9888379
An app distributed via Google Play may not modify, replace or update itself using any method other than Google Play's update mechanism. Likewise, an app may not download executable code (e.g. dex, JAR, .so files) from a source other than Google Play. This restriction does not apply to code that runs in a virtual machine or an interpreter where either provides indirect access to Android APIs (such as JavaScript in a WebView or browser).
Apps or third-party code (e.g. SDKs) with interpreted languages (JavaScript, Python, Lua, etc.) loaded at run time (e.g. not packaged with the app) must not allow potential violations of Google Play policies.
e
It's not exactly what you're looking for, but I think it'll probably suit your underlying use case
k
alright
j
redwood is about using "crossplatform" compose, not using other language
it's not a magic layer that can be passed through wire to mobile devices
it's just a way to share compose code in KMM
e
It is with Zipline
They have a sample that shows this
j
well, yes, so the zipline is
i was talking about redwood on its own
h
Yes. But you could also simple iterate any list etc of data to create views dynamically. I mean, this is the whole purpose of UI...
j
but still, how would you handle state in zipline/redwood combo?
yes, that's my whole argument
things like zipline and redwood are for really big players
huge investment, that probably does not make sense for smaller apps
e
I've done proof of concepts with both and I found a lot of upside to the redwood approach. Only downside is that the iOS team didn't want to use it 😅 I wouldn't categorize my company as a really big player.
j
it's definitely relative 😄
while i like redwood idea on it's own
i don't really see much value in ui declared on server side
maybe in few cases, like some marketing screen, but only for simple things
j
redwood is not for server-side
even redwood+zipline isn't server-side, it's client-side code shipped faster than app store releases
if you want server-side or imperative in another language then build a model that represents UI, iterate over that model in Compose, put a big
when
statement, and then have branches for each node type. it's the same thing you'd do with views, except instead of calling
addView
you call a composable. The model objects drive the logic, whether you end up calling views, composables, println, or anything else is mostly irrelevant.
e
Couldn't you point Zipline at a manifest that is generated from a dynamic endpoint and turn off caching 😝
j
yes but that would involve running the Kotlin compiler in the request path so... better bump those timeouts really high