I am new to scala so excuse me for asking such a silly question. Was looking at the example as how to program basic DSL using scala. Was wondering if it is possible to recreate it using vals instead of vars in the Order class. I tried renaming vals to vars but getting complication error in to() method as I am trying to reassign a val .
2 Answers
You need to finish the process of making your Order an immutable.
This means at least creating a constructor so that you can set all the fields on creation and changing all the mutators to create and return a new object instead of mutating and returning the current object.
As Alex said, this can be done very succinctly by making Order into a case class. But you don't have to go all the way to a case class. This will do:
class Order(val price: Int, val ins: Instrument, val qty: Int, val totalValue: Int, val trn: TransactionType, val account: String) {
def to(i: Tuple3[Instrument, Int, TransactionType]): Order = {
new Order(price, i._1, i._2, totalValue, i._3, account)
}
def maxUnitPrice(p: Int) = {
new Order(p, ins, qty, totalValue, trn, account)
}
def using(pricing: (Int, Int) => Int) = {
new Order(price, ins, qty, pricing(qty, price), trn, account)
}
def forAccount(a: String)(implicit pricing: (Int, Int) => Int) = {
new Order(price, ins, qty, pricing(qty, price), trn, a)
}
}
The case class is likely a better idea (for one thing, the copy method will make the methods more concise) - this is just to show an alternative.
You'll also need to replace the calls to the default constructor in usage of this, as it no longer exists. What you might do is create a base object:
object BasicOrder extends Order(0, null, 0, 0, null, null)
and then use that as a starting point in all your calls, for example:
BasicOrder to sell(200 bondsOf "Sun")
maxUnitPrice 300
using {
(qty, unit) => qty * unit - 500