One thing that I’ve seen done is to pass drawer instead of this, like in this example.
But if the functions are defined inside program then there’s no need to pass drawer around:
import org.openrndr.application
import org.openrndr.color.ColorRGBa
fun main() = application {
program {
fun renderSquares(count: Int, size: Int, color: ColorRGBa, etc: Int) {
repeat(count) {
drawer.fill = color
drawer.rectangle(it * 20.0, it * 20.0, size.toDouble(), size
.toDouble())
}
}
fun renderCircles(count: Int, size: Int, color: ColorRGBa, etc: Int) {
repeat(count) {
drawer.fill = color
drawer.circle(it * 20.0, it * 20.0, size.toDouble())
}
}
extend {
renderSquares(10, 80, ColorRGBa.PINK, 5)
renderCircles(15, 30, ColorRGBa.WHITE, 7)
}
}
}
Another option might be to add extension functions to drawer, so you can have those functions in external files, with the risk of polluting the Drawer object:
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.Drawer
fun Drawer.renderSquares(count: Int, size: Int, color: ColorRGBa, etc: Int) {
repeat(count) {
fill = color
rectangle(it * 20.0, it * 20.0, size.toDouble(), size.toDouble())
}
}
fun Drawer.renderCircles(count: Int, size: Int, color: ColorRGBa, etc: Int) {
repeat(count) {
fill = color
circle(it * 20.0, it * 20.0, size.toDouble())
}
}
fun main() = application {
program {
extend {
drawer.renderSquares(10, 80, ColorRGBa.PINK, 5)
drawer.renderCircles(15, 30, ColorRGBa.WHITE, 7)
}
}
}
I’m also not soo experienced with Kotlin. Probably others can propose smarter approaches 
ps. While editing posts for this forum one can click the </> button to mark it as code. It’s probably more readable like that
I changed one code block in your post as an example.