Reputation: 53866
Below function getRandomString
generates a random String from a List of characters :
def genRandomInt(lb: Int, ub: Int) = {
val rnd = new scala.util.Random
lb + rnd.nextInt(ub)
}
def getRandomString(validChars: List[Char]) = {
val size = validChars.size
val random = new scala.util.Random
val stringBuilder = new StringBuilder
val rnd = genRandomInt(0, size)
val sb = new StringBuilder
for (i <- 0 to size - 1) {
val rnd = genRandomInt(0, size)
sb.append(validChars(rnd))
}
sb.toString
} //> getRandomString: (validChars: List[Char])String
val rs = getRandomString(('a' to 'j').toList)
//> rs : String = aghdjjhjge
Is getRandomString
an example of a pure function as it does not modify state ?
Upvotes: 6
Views: 838
Reputation: 31533
No because new scala.util.Random().nextInt ...
returns something different each time, which is cogently explained by Imm.
Nevertheless you can simply pass in a seed then it will be a pure function because it will return the same random string every time. You could add the seed as a parameter or just fix it inside the random string method.
Finally, I've noticed you have written a huge amount of code to generate a random String. I suggest you look at ScalaCheck which has stacks of useful functions for generating random stuff (for unit tests), String
comes out-of-box.
If you don't want to pull in a library, you can still make that code much more concise:
def randomString(fromChars: List[Char], length: Int): String = {
val rand = new Random(1234) // Now it's pure functional because the seed is fixed
val fromCharsSize = fromChars.size // to save us repeatedly counting
List.fill(length)(fromChars(rand.nextInt(fromCharsSize))).mkString
}
Observe it returns same value every time
scala> randomString("asdf".toList, 10)
res0: String = dsfafssdsa
scala> randomString("asdf".toList, 10)
res1: String = dsfafssdsa
Upvotes: 2
Reputation: 17431
No, because it does in fact modify state. new scala.util.Random
ultimately invokes new java.util.Random
, which accesses and modifies a static (i.e. global), mutable AtomicLong
called seedUniquifier
. And therefore if this method is called multiple times then the result will change.
This is a good example of how innocent-seeming methods can hide accesses to global mutable state, which would be forbidden in a stricter functional language like Haskell (though that approach comes with its own problems).
Upvotes: 9