It would be great for DSL if I can state for a fun...
# language-proposals
m
It would be great for DSL if I can state for a function that at least one of the optional parameters must be specified, i.e. the function is otherwise either useless or an invocation invalid.
Copy code
interface SomeType

@RequiresAtLeastOneOptionalArgument
fun SomeType.with(key: String? = null, ref: Ref<*>? = null, block: () -> Unit): Unit = TODO()

fun foo(some: SomeType) {
	some.with {
		// useless with
	}
	some.with(key = "key") {
		// good
	}
}
Another example:
Copy code
@RequiresAtLeastOneOptionalArgument
fun makeBorder(width: BorderWidth? = null, style: BorderStyle? = null, color: Color? = null): Border =
	if (width != null || style != null || color != null) Border(width, style, color)
	else error("At least one property must be specified.")
makeBorder()
is then statically known to be invalid. It won’t catch
makeBorder(null)
but that’s another issue.
e
dunno if there's a better way, but with O(n) overloads you can force any one parameter to be given a non-null value
Copy code
private fun makeBorderImpl(width: BorderWidth?, style: BorderStyle?, color: Color?): Border = ...

fun makeBorder(width: BorderWidth, style: BorderStyle? = null, color: Color? = null) =
    makeBorderImpl(width = width, style = style, color = color)
fun makeBorder(style: BorderStyle, color: Color? = null) =
    makeBorderImpl(width = null, style = style, color = color)
fun makeBorder(color: Color) =
    makeBorderImpl(width = null, style = null, color = color)
m
Yeah that’s an option. But I have plenty of functions, so it’s not just
n
overloads but
n * m
(times amount of functions). That’s a looot. (You also wouldn’t be able to call that with three nullable variables in your example)
l
You can make a no argument overload that is deprecated with error level, with a clear message.
👍 6