Declaring a function that is not an expression in Kotlin

Viewed 110

How can I force a compile-time error, when somebody tries to use a function as expression that is not intended to be used like that?

fun someFunctionThatReturnsNothing() { println("Doing some stuff") }
// this should give an error:
val value = someFunctionThatReturnsNothing()

My use-case is generating a DSL where there can be name-clashes between DSL builders and sub DSLs in other builders depending on the scope of execution - e.g.:

// this is valid, calling RequestDSL.attribute(...) : Unit here,
val myRequest = request { 
  attribute {
    name = "foo"
    value = "bar"
  }
}

// this is valid, calling AttributeDSLKt.attribute(...) : Attribute
val special = attribute {
  name = "special"
  value = "ops"
}
val myRequest = request { 
  extraAttribute = special
}

// this does not compile, but is confusing,
// because the compiler does not complain where the error was made  
val myRequest = request {
  // the user intends to call AttributeKt.attribute(...) : Attribute,
  // but the compiler can only call RequestDSL.attribute(...) : Unit here
  val special = attribute {
    name = "special"
    value = "ops"
  }
  // this is confusing and should already have been prevented above:
  //    >> Type mismatch. Required: Attribute. Found: Unit. <<
  extraAttribute = special
}

If I could do something like RequestDSL.attribute(...) : void, the user wouldn't even be allowed to call attribute(...) as an expression inside the DSL. That would avoid the issue.

Can this be done somehow?

I tried Nothing, but it just makes all code unreachable after the function call.

I also tried Void, but it just force me to make the return nullable and return null instead of giving an error on the call side.

0 Answers
Related