Creating your starting point

Following the outline of our target DSL syntax, our first step is to create some type of order object that can then be configured:

  1. To do this, we'll start by creating an Order class to hold our order of pizza:
class Order(val id: String)

We've created this as a simple class with a single id property so that orders can be unique. 

  1. Next, we'll create an Item class that can be added to an Order class:
abstract class Item(val name: String)
  1. Now, we'll add a map of Item and counts to our Order class:
class Order(val id: String) : Item("Order")  {
val items: MutableMap<Item, Int> = mutableMapOf()
}
  1. With our Item map in place, we're ready to create an order. To do this, we'll create a top-level function:
fun order(init: Order.() -> Unit): Order {
val order = Order(UUID.randomUUID().toString())
order.init()
return order
}

The following two interesting elements should be observed in relation to this function:

These two characteristics allow us to call the function and understand that we are creating a new order, which helps enforce the declarative nature of the DSL. This also allows us to configure the Order instance within a passed lambda:

val order = order {
println(this.id)

}

Now, we're ready to start adding items to our order.