If I understand correctly every time you call execute on the object, it shall use a different element. Then because the object has to encapsulate state, so there's no way around the var
var hosts = collection.immutable.Queue ++ optHosts.getOrElse(List())
def url: String = {
val(element,queue) = hosts.pop
hosts = queue.enqueue(element)
element
}
Regarding your questions...
Somehow I would have to remember an index right?
Yes, see above. But also no, see below.
Is that one of the cases where it doesn't make sense to use immutable types?
Depends. If you want to keep your object RoundRobin
then clearly, that object is mutable, and you so you only have the choice between mutable vals and immutable vars. (well you could also have vars that point to mutable structures, but why would you do that?)
On the other hand you can also opt for a totally different approach:
class RoundRobin private(left: List[String], all: List[String]) {
def this(all :List[String]) = this(all, all)
assume(all.nonEmpty)
val theElement = left.headOption.getOrElse(all.head)
def nextRoundRobin = new RoundRobin(if(left.nonEmpty) left.tail else all, all)
def execute = {
// do something with theElement
println(theElement)
// return an object that will execute on the next element
nextRoundRobin
}
}
new RoundRobin(List("1","2")).execute.execute.execute
// prints 1 2 1
When you use this version of RoundRobin, every time you call execute it will give you a round robin object that will use the next element in round-robin fashion. Clearly the object using RoundRobin can again either be mutable or immutable.