in JavaScript string templates, there's a mechanis...
# javascript
j
in JavaScript string templates, there's a mechanism where if you pass the string template to a function without brackets, the string template is split into pieces
Copy code
function blah(...args) { console.log(args) }
running this:
Copy code
blah`testing-${1}-${2}-${3}`
I get a list of parts (separators between ${}), pre/post-fix and values
Copy code
0: (4) ['testing-', '-', '-', '', raw: Array(4)]
1: 1
2: 2
3: 3
length: 4
Is there anything planned for Kotlin that would allows taking a String template and splitting it up like that at compile time? (similar to how to trimIndent() is processed at compile time, a compile time mechanism that can decompose a String template into its static and dynamic parts)
Copy code
val blah = """  
    testing-${1}-$var2-${var3 + 1}
""".trimIndent()

blah.decompose() // outputting the static parts, listOf("testing", "-", "-", "") and the dynamic parts, listOf(1, var2, { var3 + 1}())
Just wondering how else one would replicate what lit-html, lit-element, uhtml and many of these JS frameworks are doing in pure JavaScript
g
Idea from a noob: I imagine you could write an extension function, based on Regex and returning a tuple. And if you can write one for runtime, then you could use KSP to generate code at compile time matching your need. (Not sure if you can really use the template syntax tho.) I'd imagine the string to be a constant in an annotation value, not sure if it's your goal here.
j
the extension function idea would not work unfortunately as the template is parsed by the time your extension function gets it. For extension functions to work, you'd need to replace the ${ } with some other symbol, let's say #{ }, but then #{ blah } can't be checked at compile time and neither do you get compiler assistance in IntelliJ and if you want to do anything more advanced, #{ value.map{}.filter.{}..... } you'll have to build it on your own, unfortunately no Kotlin to JavaScript compiler assistance either. I can off course manually split it,
Copy code
template = arrayOf(
  "<div>", 
      this.firstName, 
  "</div>",
  """<div><input value=" """,
      this.lastName,
  """/></div>)
but that would about as usable as it looks I'm not sure if KSP can do it, it certainly sits in the right place to do it and so does ArrowMeta In order to do server side rendering with a JVM framework that then re-uses the same templates in the browser with ES6 template literals (which btw is blazing fast), you will need some sort of mechanism that can split String templates at compile time. Short term I'll most likely need to build a compiler plugin to achieve this A good read for some context: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates and: https://viperhtml.js.org/hyperhtml/documentation/#introduction-0