https://kotlinlang.org logo
Join SlackCommunities
Powered by
# dsl
  • v

    vladimirsitnikov

    11/24/2021, 7:36 AM
    Before you read the question: I understand what
    @DslMarker
    means. Can anyone please clarify what
    @DslMarker
    annotation on a function means? The official documentation (see https://kotlinlang.org/docs/type-safe-builders.html#scope-control-dslmarker, https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-dsl-marker/) describes that the annotations affect classes, interfaces, and lambdas only. The documentation provides no clue on the meaning of
    @DslMarker fun html(...) {
    In practice, both
    kotlinx-html
    and
    ktor
    annotate their DSL functions with the corresponding DslMarker annotation: https://github.com/Kotlin/kotlinx.html/blob/24ef7f418687ce4241ec111f757b09e8b4f5bf79/src/commonMain/kotlin/generated/gen-tags-p.kt#L49-L50 Here's an example:
    Copy code
    @HtmlTagMarker
    inline fun PICTURE.img(alt : String? = null, src : String? = null, classes : String? = null, crossinline block : IMG.() -> Unit = {}) : Unit =
        IMG(attributesMapOf("alt", alt,"src", src,"class", classes), consumer).visit(block)
    Of course, their
    Tag
    interface is annotated (
    PICTURE
    and
    IMG
    implement that interface):
    Copy code
    @HtmlTagMarker
    interface Tag {
    However, my question is what does annotation on function mean? As a side-effect, I noticed that IDEA 2021.2.3 removes italic style from extension functions that have
    @DslMarker
    annotation. Is it a valid hack? Should it be documented somehow?
    w
    • 2
    • 1
  • k

    karn

    01/12/2022, 7:57 PM
    Is the kotlin-dsl library published to any other repo other than plugins.gradle.org? looks like they're having some issues and the library is no longer resolving
  • a

    Advitiay Anand

    03/14/2022, 9:07 PM
    Hey, what would be a good place to start learning about DSLs? I would like to create a fun little DSL as a silly project :)
    k
    m
    • 3
    • 2
  • a

    Alex Cruise

    08/19/2022, 11:02 PM
    Not sure whether to post in here or #opensource but I have a question about https://github.com/h0tk3y/better-parse; I’ve filed https://github.com/h0tk3y/better-parse/issues/58 about it
  • a

    Alex Cruise

    08/22/2022, 3:58 PM
    ^^ @h0tk3y sorry to tag you but if you have a few minutes I’d appreciate your thoughts 🙂
  • a

    Alex Cruise

    08/22/2022, 4:12 PM
    Specifically I’m wondering how to add a negative lookahead operator to better-parse; I’ve spitballed something in a comment but I have no idea if it’s right
  • s

    Shawn

    08/22/2022, 4:45 PM
    why is it called negative lookahead anyhow? wouldn’t you just look behind
  • a

    Alex Cruise

    08/22/2022, 4:49 PM
    not sure if trolling… 😉
  • a

    Alex Cruise

    08/22/2022, 4:50 PM
    this is
    x not-followed-by y
    🙂
  • a

    Alex Cruise

    08/22/2022, 4:51 PM
    wikipedia says:
    The not-predicate expression !e succeeds if e fails and fails if e succeeds, again consuming no input in either case.
  • a

    Alex Cruise

    08/22/2022, 4:51 PM
    come to think of it, it doesn’t sound like negation is synonymous with not-followed-by
  • a

    Alex Cruise

    08/23/2022, 12:42 AM
    WIP: https://github.com/h0tk3y/better-parse/pull/59
  • c

    Curtis Ullerich

    10/06/2022, 8:39 PM
    I wrote a toy DSL for tree structure/property matching. this lets me write something like
    Copy code
    val matcher = plus { num { where { it.value > 2 } } variable {} }
    val ast = Addition(Number(3), Variable("y"))
    val matched = matcher.matches(ast)
    I'm hoping to also support property extraction. I implemented something that works, but it feels gross using nullable vars like this:
    Copy code
    var value: Int? = null
    var name: String? = null
    val extracter = plus { num { extract { value = it.value } } variable { extract { name = it.name } } }
    val ast = Addition(Number(3), Variable("y"))
    extracter.extractFrom(ast)
    println("$value $name") // 3 y
    Is there a pattern I could use to implement something more like this?
    Copy code
    val (value: Int, name: String) = extracter.extractFrom(ast) ?: return null
    🆒 1
    m
    • 2
    • 12
  • v

    Viktor Sirotin

    01/28/2023, 4:18 PM
    https://viktor-sirotin.medium.com/kotunil-si-units-kotlin-part-one-introduction-to-kotunil-3b5add3e7acc
  • v

    Viktor Sirotin

    01/31/2023, 1:00 PM
    I have now published the second article in my series on KotUniL. https://viktor-sirotin.medium.com/kotunil-si-units-kotlin-part-two-advanced-features-50b1fc85c5d7
    👍 1
    👏 1
  • d

    Dirk Hoffmann

    03/14/2023, 3:15 PM
    I am trying to give the "parent" block ability to implement the same closure(s) as their "child" block, but restricting to certain interfaces. I of course can give the parent an implementation which implements all interface "flavours", and still restrict the children to more specific interfaces ... everything works out, but then, DESPITE having @DslMarkers on ALL my classes, child-blocks STILL see clauses of the parent WITHOUT explicitly qualifying them (
    <mailto:this@dsl.xxx|this@dsl.xxx>
    ) and I don't understand WHY. I constructed a single executable File to showcase my "problem" (at the end of the file/code)
    DslMarker not honoured.cpp
    • 1
    • 2
  • b

    Bradleycorn

    05/10/2023, 2:31 PM
    Beginner DSL question … I have an app that is made up of several modules, and each module (as well as the app itself) needs some configuration. I was thinking of building a DSL to handle this configuration, so that you could do something like:
    Copy code
    val appConfig = AppConfig {
        name = "My App"
    
        storage {
            filePath = "/path/to/some/dir"
        }
        
        network {
             baseUrl = "<https://api.mysite.com>"
             authType = "Basic"
        }
    }
    Wondering if someone might provide some advice on the best way to do this? I have written some code that works, but as this is my first attempt, I’m wondering if I’ve done it the “right”/“best” way. Code is in the 🧵
    y
    a
    m
    • 4
    • 4
  • d

    Dirk Hoffmann

    05/16/2023, 7:28 AM
    is it on purpose (and if so why) that I cannot use the context object for assigning constructor default values, BUT I CAN use it in class init { } block???
    Copy code
    ctxObjs access does NOT work in constructor:
    
    class CtxClass(val value: Int)
    
    data class CtxStore(val ctxObjs: MutableMap<String, CtxClass> = mutableMapOf())
    
    context(CtxStore)
    class SomeClass(var ctxO: CtxClass = ctxObjs["someRef"]!!) { // <-- Unresolved reference: ctxObjs
        fun someFun() = "SomeClass(${ctxO.value})"
    }
    ctxObjs access does work in init block:
    Copy code
    class CtxClass(val value: Int)
    
    data class CtxStore(val ctxObjs: MutableMap<String, CtxClass> = mutableMapOf())
    
    context(CtxStore)
    class SomeClass(var ctxO: CtxClass = CtxClass(0)) {
        init {
            ctxO = ctxObjs["someRef"]!!
        }
        fun someFun() = "SomeClass(${ctxO.value})"
    }
    e
    • 2
    • 1
  • s

    smallufo

    07/09/2023, 9:18 AM
    My mini notes about DSL and context magic https://medium.com/@smallufo/kotlin-context-receivers-and-dsl-magic-73aee25bca23
  • m

    Max

    07/09/2023, 7:37 PM
    Kabu generates code for complex Kotlin DSLs in less than 1 minute. Feedback is appreciated! https://github.com/bipokot/Kabu
    🦸 1
    K 2
    K 1
    🆒 2
    a
    m
    • 3
    • 2
  • m

    Max

    08/04/2023, 7:16 AM
    Kabu 0.24.0 has been released. • Support for generic target functions and generic extension contexts • New @Context annotation to reduce boilerplate (marks primary constructor of a class as @ContextCreator)
  • u

    윤동환

    08/10/2023, 2:07 AM
    What is the choosing guide between
    T.() -> R
    and
    (T) -> R
    for function type? First one called lambda with receiver and second one is the first class function.
    w
    s
    • 3
    • 2
  • n

    neerav

    08/31/2023, 8:48 AM
    Hello 👋 Need input/help in below question. How can we move specific configuration from Android app’s level build.gradle.kts to dedicated gradle.kts. Example : in Main app level gradle file multiple blocks are there.
    android { signingConfig, defaultConfig etc }
    dependencies {}
    From above Case I am able to move
    dependencies { }
    into separate
    dependencies.gradle.kts
    file. Now i am facing issue when I am trying to move signingConfig & defaultConfig etc into separate
    flavorSigning.gradle.kts
    file Can anyone please help me how can we move defaultConfig and productFlavor code into dedicated gradle.kts file ? I am not sure where this question should be asked so please guide me if its in wrong channel. Thank you
    m
    • 2
    • 1
  • w

    wakingrufus

    10/18/2023, 7:14 PM
    Is there a way to apply a Dsl marker scope to external classes? for example, I am wrapping spring's bean definition dsl, and I have my own dsl marker, but once you are in a receiver for the spring dsl, the scope is not restricted anymore.
  • y

    yolocat

    01/19/2024, 4:57 PM
    hi guys! just a question, does instantiating (ClassName()) act as an invoke, or can I add functionality to instantiating in some other way? currently have a function add that takes in a Component, though this looks rather bad. can I automatically call add on every instantiated object in my dsl? thanks!
    m
    v
    • 3
    • 7
  • m

    Marco Pierucci

    02/23/2024, 12:47 PM
    👋 Is there a safe approach at accessing version catalog
    libs
    notation within convention plugins? I've seen some using
    val libs = the<LibrariesForLibs>()
    But as per https://github.com/gradle/gradle/issues/19813 thats not intended
    g
    • 2
    • 1
  • r

    rdhruva

    06/02/2024, 3:32 PM
    When designing a DSL, is it possible to use a lambda to collect list inputs? I have not been able to find a way to make it work. What I want:
    Copy code
    dependsOn {
      "foo"
      "bar"
      "baz"
    }
    and then I can "collect" the 3 as a list. What I ended up doing for now is:
    Copy code
    dependsOn {
      add("foo")
      add("bar")
      add("baz")
    }
    And the definition looks like:
    Copy code
    fun dependsOn(init: MutableList<String>.() -> Unit)
    Is there a better way to do this, such that I don't need the
    add(...)
    ?
    w
    m
    • 3
    • 7
  • w

    wakingrufus

    07/22/2024, 11:07 PM
    I have a new OSS project that supports the functional DSL approach to Spring Boot in Kotlin. If that sounds interesting to you, check it out on GitHub: https://github.com/wakingrufus/spring-funk
    s
    • 2
    • 1
  • r

    rad

    09/12/2024, 12:22 PM
    Do you think it is feasible to write a GLSL DSL within Kotlin? I feel like an annoying thing would be having keywords and statements like
    if
    as they're already used by the language, so you'd need
    Copy code
    `if` (variableA eq variableB)
    which feels slightly annoying to use. Is there any alternatives (compiler plugin?) or would it just not be possible? Example of what I'm talking about:
    Copy code
    buildGlslShader { // this: GlslShaderContext
        glPosition = projMat * modelViewMat * vec4(position, 1.0)
        val iColor = ivec3(color.xyz * 255 + vec3(0.5))
    
        `if` (iColor eq ivec3(78, 92, 36) {
            // Change some stuff...
         }
    }
    e
    m
    • 3
    • 14
  • a

    alexhelder

    04/24/2025, 11:15 PM
    Is it possible to have DSL like:
    Copy code
    saver {
      val key1 = …
      val key2 = …
      save = { reference key1/2 },
      restore = { reference key1/2 }
    }
    specifically i would like to declare variables at the top level of the block but reference them in child lambdas
    j
    • 2
    • 1