https://kotlinlang.org logo
Title
a

andyg

07/24/2022, 5:31 AM
Are Kotlin DSLs (typesafe builders) only for use internally by application developers? Want to create and expose a DSL for "power" end-users to define some complex objects that are currently quite tedious via a point-and-click UI, but think this is not possible. Allowing them to define via JSON/YAML is an option but the DSL format is even easier to use and validate.
v

Vampire

07/24/2022, 7:08 AM
Sure it is. Perfect example is Gradle. It provides a Kotlin DSL for its users to write build scripts in.
a

Alex

07/24/2022, 11:36 AM
I wrote a blog post about just this, hope you find it helpful https://blog.devgenius.io/writing-a-dsl-in-kotlin-42a9029b93a6
a

andyg

07/25/2022, 6:55 AM
@Vampire The people who use the Gradle Kotlin DSL are application developers. I'm talking about the end users of an application... like could they build an object with the DSL in a web form and submit it? Or write it in a separate file (instead of a JSON/YAML file) and reference it on the command line for processing?
v

Vampire

07/25/2022, 7:00 AM
What is the difference whether they are developers or not? The point is, the build script is a file with Kotlin DSL content that is interpreted by Gradle. So yes, you can also submit that via web form or supply a file on the command line. Latter you can also do with Gradle build scripts.
a

andyg

07/25/2022, 7:04 AM
Maybe I'm not asking the right way... can you submit a file or string following a DSL's rules to a compiled Kotlin app and have the app convert it into Kotlin objects?
The more I'm thinking about this, I think the difference is the DSL requires the compiler to create objects. Gradle reads the file pre-compilation so it works. End users are interacting with a compiled application. JSON libs like Moshi or Jackson perform serialization (JSON <--> Kotlin objects). Those libs don't exist for DSLs, the compiler does it.
v

Vampire

07/25/2022, 8:38 AM
How often do I need to repeat it? Yes, it is. And no, Gradle does not need any pre-compilation. It just does it as you usually execute the same build script several times and so it is more performant to precompile and use the result than to work from the source for each invocation.
You can either need the embedded compiler to compile in your application and then execute if you have similar needs, or you can simply use #scripting to just interpret the script on-the-fly.
a

andyg

07/25/2022, 8:54 AM
OK so if I receive a JSON file as the body of an HTTP post request, I can use Jackson or Moshi to deserialize it. How do I do it if instead of JSON, the POST body is an object definition as a DSL format?
v

Vampire

07/25/2022, 9:02 AM
You can use Moshi or Jackson, but I would actually use
kotlinx.serialization
. And I already told you that you use #scripting support for example. Your DSL is a Kotlin Script and you evaluate it. How exactly this is done depends on the concrete requirements, but I guess you should start with reading the documentation and then maybe ask in the proper channel.
a

andyg

07/25/2022, 9:42 AM
I wish this was a helpful exchange because this is what I would like to accomplish however I don't see any examples of what you say is "simple" in 3 days of Google searching and documentation review. Let me be clear I am not talking about Gradle, I am trying to implement a DSL (as an alternative to JSON or YAML), as a way for end users of my JVM web (ktor or http4k) application to submit data objects. In other words: instead of submitting JSON
{ 'type':'car',
  'model':'Subaru',
  'parts':{
    'tires':{'brand':'Yokohama', 'size':'285/35R19'},
    'oil':{'brand':'Mobil 1', 'viscosity':'0W40'},
  }
}
the users could submit something like this:
car {
  model = 'subaru'
  tires {
    brand = 'Yokohama'
    size = '285/35R19'
  }
  oil(brand = 'Mobil 1', viscosity = '0W40')
}
v

Vampire

07/25/2022, 10:07 AM
I wish this was a helpful exchange
Me too, but you just repeat your inital question with different words multiple times and do not accept the answer I already understood when you asked the first time. Doesn't change my answer. And I never said it is "simple", I said it is "possible" and that you should read about and ask in #scripting on how to actually do it best.
I just provided Gradle as an example where exactly that is done. A user of Gradle provides something using a Kotlin DSL and Gradle interprets and processes it.
d

David Saff

07/25/2022, 1:33 PM
This may be something close to what you're hoping to do? https://kotlinexpertise.com/run-kotlin-scripts-from-kotlin-programs/
g

Guillaume Taffin

07/25/2022, 5:00 PM
Just some ‘side remarks’: • I don’t really know what is the confidence your end users have with writing code but unless they actually are programmers I would not expect to much external users to especially enjoy using very programmatic apis. Even though it is possible, you have to balance the cost to potentially support those users that are not as comfortable with coding rules… Maybe it is worth it 🙂 • More importantly, when I read ideas where people want code to be interpreted at runtime I usually think it is not quite a good idea since it is a very nice back-door to inject malicious code. The recent Log4J vulnerability is a good example of where that kind of idea can lead… you know better than me what are your needs of course, and you probably already considered that… but I still think it’s worth emphasizing it for those who might read this feed 😛
a

andyg

07/26/2022, 7:31 AM
@Guillaume Taffin Great points, you are absolutely right. I'm helping a company build a tool for "power users" to bypass a very old desktop application. Define the objects using JSON rather than point-and-click through more than a dozen individual screens with lots of options. I thought instead of JSON or YAML maybe I could design a DSL that would be even easier and have some business logic built in. But you make a good point -- using a DSL you are writing code, it might look similar to JSON but it is much more powerful. And the more I think about that (and the fact they have no tooling), the less I expect the end users to be able to be successful. Leaning more towards writing a JSON Schema doc, using an off-the-shelf JSON validator and calling it a day. Thanks.
@David Saff Thank you, this is definitely the closest I've seen to what I was imagining. However the scripts still involve some Kotlin boilerplate such as `import`s and variable declarations. Even if I were to build a system to insert just the parts between
html {
and
}
the end users wouldn't have the tooling (code completion, all the other advantages of an IDE) to rapidly build a valid object. I will look into this more however, thank you.
@Vampire I appreciate your help Bjorn, perhaps some things that seem basic to you about how Gradle works or about the Scripting API are a bit higher-level than the applications I've built in the past. Thank you.
v

Vampire

07/26/2022, 8:10 AM
It's Björn, or Bjoern, not Bjorn. ;-) Why are you constantly putting words in my mouth? I also never said how Gradle is doing it is basic or easy, let alone you would be able to copy&paste. I just showed it as example that is doing exactly what you asked for to answer the question whether it is possible to do so and told you where to better ask about the topic.
l

Lukáš Kúšik

08/01/2022, 8:35 PM
@andyg This might also be relevant for you https://www.jetbrains.com/mps/
a

andyg

08/03/2022, 6:08 AM
wow, this is actually very cool. thanks!