Creating immutable instances and modifying copies in an idiomatic way - class

I would like to conditionally create copies of an object instance depending on information external to that instance. Most of the information in the copies will be the same as the original, but some of the information will need to change. This information is being passed around between actors, so I need the objects to be immutable in order to avoid strange concurrency-related behavior. The following toy code is a simple example of what I would like some help with.
If I have the following code:
case class Container(condition:String,amount:Int,ID:Long)
I can do the following:
val a = new Container("Hello",10,1234567890)
println("a = " + a)
val b = a.copy(amount = -5)
println("b = " + b)
println("amount in b is " + b.amount)
and the output is
a = Container(Hello,10,1234567890)
b = Container(Hello,-5,1234567890)
amount in b is -5
I can also conditionally create copies of the object doing the following:
import scala.Math._
val max = 3
val c = if(abs(b.amount) >= max) b.copy(amount = max,condition="Goodbye") else if(abs(b.amount) < max) b.copy(amount = abs(b.amount))
println("c = " + c)
If I set the amount in the b object to -5, then the output is
c = Container(Goodbye,3,1234567890)
and if I set the amount in the b object to -2, then the output is
c = Container(Hello,2,1234567890)
However, when I try to print out c.amount, it gets flagged by the compiler with the following message
println("amount in c is " + c.amount)
value amount is not a member of Any
If I change the c object creation line to
val c:Container = if(abs(b.amount) >= max) b.copy(amount = max,condition="Goodbye") else if(abs(b.amount) < max) b.copy(amount = abs(b.amount))
I get the compiler error
type mismatch; found: Unit required:
Container
What is the best, idiomatic way of conditionally creating immutable instances of case classes by copying existing instances and modifying a value or two?
Thanks,
Bruce

You are not including a final else clause. Thus the type of c is Any -- the only type that is supertype both of Container and Unit, where Unit is the result of not including a catch-all else clause. If you try to force the result type to be Container, by writing c: Container =, the compiler now tells you the missing else clause resulting in Unit is not assignable to Container.
Thus
val c = if (abs(b.amount) >= max) {
b.copy(amount = max, condition = "Goodbye")
} else if (abs(b.amount) < max) {
b.copy(amount = abs(b.amount))
} else b // leave untouched !
works. The compiler isn't smart enough to figure out that the last else clause cannot be logically reached (it would need to know what abs and >= and < means, that they are mutual exclusive and exhaustive, and that abs is purely functional, as is b.amount).
In other words, since you know that the two clauses are mutually exclusive and exhaustive, you can simplify
val c = if (abs(b.amount) >= max) {
b.copy(amount = max, condition = "Goodbye")
} else { // i.e. abs(b.amount) < max
b.copy(amount = abs(b.amount))
}

Related

Scala3 inline if reuse result of function

val num = 3
val x = if (func(num) > 3) func(num) else 4
How can i avoid calling func(num) twice here? My project is fully functional so calling func(num) twice is guaranteed to yield the same result. Does the compiler optimize this automatically? I am aware of this:
val num = 3
val x = List(num).map(f(_)).map(a => if (a > 3) a else 4).head
EDIT: I'm looking for a way to improve this
val temp = tl.indexWhere(<bool>)
val insertIndex = if(temp == -1) tl.size else temp
The Scala compiler will generally not know if a function is pure, so it cannot perform that optimization automatically.
val temp = tl.indexWhere(???)
val insertIndex = if(temp == -1) tl.size else temp
Is very likely the clearest and (by explicitly preventing double evaluation) most performant expression of this logic. Assuming that temp is a local variable, the Scala compiler can see that it's not used later in your function/method and reuse the local variable slot.
Just in case you want to make it abundantly clear that the local variable is only used for this particular block of code, you could utilize … a block of code:
val insertIndex = { val temp = tl.indexWhere(<bool>); if (temp == -1) tl.size else temp }
or
val insertIndex = {
val temp = tl.indexWhere(<bool>)
if (temp == -1) tl.size else temp
}
As mentioned in another answer, Scala cannot, generally, know that tl.indexWhere is pure, since Purity Analysis is equivalent to solving the Halting Problem.
Not sure if this is an improvement but you can use pattern matching with guard:
val num = 3
val x = num match {
case v if v > 3 => v
case _ => 4
}
Or in second case simply:
val insertIndex = tl.indexWhere(...) match {
case -1 => tl.size
case v => v
}

How to find the largest multiple of n that fits in a 32 bit integer

I am reading Functional Programming in Scala and am having trouble understanding a piece of code. I have checked the errata for the book and the passage in question does not have a misprint. (Actually, it does have a misprint, but the misprint does not affect the code that I have a question about.)
The code in question calculates a pseudo-random, non-negative integer that is less than some upper bound. The function that does this is called nonNegativeLessThan.
trait RNG {
def nextInt: (Int, RNG) // Should generate a random `Int`.
}
case class Simple(seed: Long) extends RNG {
def nextInt: (Int, RNG) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL // `&` is bitwise AND. We use the current seed to generate a new seed.
val nextRNG = Simple(newSeed) // The next state, which is an `RNG` instance created from the new seed.
val n = (newSeed >>> 16).toInt // `>>>` is right binary shift with zero fill. The value `n` is our new pseudo-random integer.
(n, nextRNG) // The return value is a tuple containing both a pseudo-random integer and the next `RNG` state.
}
}
type Rand[+A] = RNG => (A, RNG)
def nonNegativeInt(rng: RNG): (Int, RNG) = {
val (i, r) = rng.nextInt
(if (i < 0) -(i + 1) else i, r)
}
def nonNegativeLessThan(n: Int): Rand[Int] = { rng =>
val (i, rng2) = nonNegativeInt(rng)
val mod = i % n
if (i + (n-1) - mod >= 0) (mod, rng2)
else nonNegativeLessThan(n)(rng2)
}
I have trouble understanding the following code in nonNegativeLessThan that looks like this: if (i + (n-1) - mod >= 0) (mod, rng2), etc.
The book explains that this entire if-else expression is necessary because a naive implementation that simply takes the mod of the result of nonNegativeInt would be slightly skewed toward lower values since Int.MaxValue is not guaranteed to be a multiple of n. Therefore, this code is meant to check if the generated output of nonNegativeInt would be larger than the largest multiple of n that fits inside a 32 bit value. If the generated number is larger than the largest multiple of n that fits inside a 32 bit value, the function recalculates the pseudo-random number.
To elaborate, the naive implementation would look like this:
def naiveNonNegativeLessThan(n: Int): Rand[Int] = map(nonNegativeInt){_ % n}
where map is defined as follows
def map[A,B](s: Rand[A])(f: A => B): Rand[B] = {
rng =>
val (a, rng2) = s(rng)
(f(a), rng2)
}
To repeat, this naive implementation is not desirable because of a slight skew towards lower values when Int.MaxValue is not a perfect multiple of n.
So, to reiterate the question: what does the following code do, and how does it help us determine whether a number is smaller that the largest multiple of n that fits inside a 32 bit integer? I am talking about this code inside nonNegativeLessThan:
if (i + (n-1) - mod >= 0) (mod, rng2)
else nonNegativeLessThan(n)(rng2)
I have exactly the same confusion about this passage from the Functional Programming in Scala. And I absolutely agree with jwvh's analysis - the statement if (i + (n-1) - mod >= 0) will be always true.
In fact, if one tries the same example in Rust, the compiler warns about this (just an interesting comparison of how much static checking is being done). Of course the pencil and paper approach of jwvh is absolutely the right approach.
We first define some type aliases to make the code match closer to the Scala code (forgive my Rust if its not quite idiomatic).
pub type RNGType = Box<dyn RNG>;
pub type Rand<A> = Box<dyn Fn(RNGType) -> (A, RNGType)>;
pub fn non_negative_less_than_(n: u32) -> Rand<u32> {
let t = move |rng: RNGType| {
let (i, rng2) = non_negative_int(rng);
let rem = i % n;
if i + (n - 1) - rem >= 0 {
(rem, rng2)
} else {
non_negative_less_than(n)(rng2)
}
};
Box::new(t)
}
The compiler warning regarding if nn + (n - 1) - rem >= 0 is:
warning: comparison is useless due to type limits

Type Mismatch Unit and String in Scala

I am trying to take from a list of tuples (e.g. List[(String, String)]) some words that have the difference between the number of syllables smaller than 2.
If that is ok, I return them - however, I have some issues: I get Unit found and String expected.
def ecrire():String = {
// Choose deux output: List[(Word, Word)]
// I take every tuple of the list and proceed as the element "b"
for (b <- choose_deux()){
val x = b._1
val y = b._2
val diff = Math.abs(x.syllabes - y.syllabes)
// Check if difference between syllables is smaller than 2
if(diff <= 2)
return x.toString() + "\n" + y.toString()
}
}
}
Now I know that probably I have to do a yield at the bottom, but yield what exactly? The idea is that if the condition shown in the "if" is respected, I write the string made of these two elements.
The error is shown at the for loop: type mismatch; found: Unit; required: String
Could you please help me a bit? I am still new and learning!
Type mismatch error is because your for loop doesn't have else statement and you can't return using if inside a for loop. So for loop is not returning anything so scala compiler assumes the return type to be () i.e. unit() and you have defined the return type as String.
Defining the functions in the following way should solve your issue
def diff(x) = Math.abs(x._1.syllabes - x._2.syllabes)
for (b <- choose_deux() if(diff(b) <= 2)) yield b._1.toString() + "\n" + b._2.toString()

scala: what is the inner class method for dynamic scoping?

i'm trying to evaluate all 3 methods of dynamic scoping described here (https://wiki.scala-lang.org/display/SYGN/Dynamic-scope) and i understand all but the "inner class method". it is described as follows:
It is possible to achieve a similar effect to dynamic scoping using nested class definitions. By defining the entire state-consuming code as inner classes of a state object, and instantiating that object each time a new global state is required, all the contained code gets direct access to the state variables via the parent reference.
To avoid defining the entire program in a single file, this approach for most purposes mandates the use of component mixins in order to compose the program into a single class.
I don't quite understand this - is it possible for someone to give some example code showing this? The second approach of implicit parameters makes sense to me, but the article also suggests that it can be combined with the inner class method and I don't quite see that either. Thanks!
Like this:
case class Board(rows: Int, columns: Int) {
case class Pos(row: Int, column: Int) {
require(0 <= row && row < rows && 0 <= column && column < columns)
def neighbors = for {
nRow <- Set(row - 1, row, row + 1)
if 0 <= nRow && nRow < rows
nColumn <- Set(column - 1, column, column + 1)
if 0 <= nColumn && nColumn < columns
if (nRow, nColumn) != (row, column)
} yield Pos(nRow, nColumn)
}
}
Here, Pos refers to a "context" that is on Board: rows and columns. For example:
scala> val board = Board(5, 5)
board: Board = Board(5,5)
scala> val pos = board.Pos(0, 0)
pos: board.Pos = Pos(0,0)
scala> println(pos.neighbors)
Set(Pos(0,1), Pos(1,0), Pos(1,1))
Changes in one Board as seen by the Pos associated with that instance, but not with others:
scala> val board2 = Board(2, 2)
board2: Board = Board(2,2)
scala> println(board.Pos(1,1).neighbors+"\n"+board2.Pos(1, 1).neighbors)
Set(Pos(1,0), Pos(1,2), Pos(2,0), Pos(2,1), Pos(0,0), Pos(2,2), Pos(0,1), Pos(0,2))
Set(Pos(0,0), Pos(0,1), Pos(1,0))

How do I break out of a loop in Scala?

How do I break out a loop?
var largest=0
for(i<-999 to 1 by -1) {
for (j<-i to 1 by -1) {
val product=i*j
if (largest>product)
// I want to break out here
else
if(product.toString.equals(product.toString.reverse))
largest=largest max product
}
}
How do I turn nested for loops into tail recursion?
From Scala Talk at FOSDEM 2009 http://www.slideshare.net/Odersky/fosdem-2009-1013261
on the 22nd page:
Break and continue
Scala does not have them. Why?
They are a bit imperative; better use many smaller functions
Issue how to interact with closures.
They are not needed!
What is the explanation?
You have three (or so) options to break out of loops.
Suppose you want to sum numbers until the total is greater than 1000. You try
var sum = 0
for (i <- 0 to 1000) sum += i
except you want to stop when (sum > 1000).
What to do? There are several options.
(1a) Use some construct that includes a conditional that you test.
var sum = 0
(0 to 1000).iterator.takeWhile(_ => sum < 1000).foreach(i => sum+=i)
(warning--this depends on details of how the takeWhile test and the foreach are interleaved during evaluation, and probably shouldn't be used in practice!).
(1b) Use tail recursion instead of a for loop, taking advantage of how easy it is to write a new method in Scala:
var sum = 0
def addTo(i: Int, max: Int) {
sum += i; if (sum < max) addTo(i+1,max)
}
addTo(0,1000)
(1c) Fall back to using a while loop
var sum = 0
var i = 0
while (i <= 1000 && sum <= 1000) { sum += 1; i += 1 }
(2) Throw an exception.
object AllDone extends Exception { }
var sum = 0
try {
for (i <- 0 to 1000) { sum += i; if (sum>=1000) throw AllDone }
} catch {
case AllDone =>
}
(2a) In Scala 2.8+ this is already pre-packaged in scala.util.control.Breaks using syntax that looks a lot like your familiar old break from C/Java:
import scala.util.control.Breaks._
var sum = 0
breakable { for (i <- 0 to 1000) {
sum += i
if (sum >= 1000) break
} }
(3) Put the code into a method and use return.
var sum = 0
def findSum { for (i <- 0 to 1000) { sum += i; if (sum>=1000) return } }
findSum
This is intentionally made not-too-easy for at least three reasons I can think of. First, in large code blocks, it's easy to overlook "continue" and "break" statements, or to think you're breaking out of more or less than you really are, or to need to break two loops which you can't do easily anyway--so the standard usage, while handy, has its problems, and thus you should try to structure your code a different way. Second, Scala has all sorts of nestings that you probably don't even notice, so if you could break out of things, you'd probably be surprised by where the code flow ended up (especially with closures). Third, most of Scala's "loops" aren't actually normal loops--they're method calls that have their own loop, or they are recursion which may or may not actually be a loop--and although they act looplike, it's hard to come up with a consistent way to know what "break" and the like should do. So, to be consistent, the wiser thing to do is not to have a "break" at all.
Note: There are functional equivalents of all of these where you return the value of sum rather than mutate it in place. These are more idiomatic Scala. However, the logic remains the same. (return becomes return x, etc.).
This has changed in Scala 2.8 which has a mechanism for using breaks. You can now do the following:
import scala.util.control.Breaks._
var largest = 0
// pass a function to the breakable method
breakable {
for (i<-999 to 1 by -1; j <- i to 1 by -1) {
val product = i * j
if (largest > product) {
break // BREAK!!
}
else if (product.toString.equals(product.toString.reverse)) {
largest = largest max product
}
}
}
It is never a good idea to break out of a for-loop. If you are using a for-loop it means that you know how many times you want to iterate. Use a while-loop with 2 conditions.
for example
var done = false
while (i <= length && !done) {
if (sum > 1000) {
done = true
}
}
To add Rex Kerr answer another way:
(1c) You can also use a guard in your loop:
var sum = 0
for (i <- 0 to 1000 ; if sum<1000) sum += i
Simply We can do in scala is
scala> import util.control.Breaks._
scala> object TestBreak {
def main(args : Array[String]) {
breakable {
for (i <- 1 to 10) {
println(i)
if (i == 5)
break;
} } } }
output :
scala> TestBreak.main(Array())
1
2
3
4
5
Since there is no break in Scala yet, you could try to solve this problem with using a return-statement. Therefore you need to put your inner loop into a function, otherwise the return would skip the whole loop.
Scala 2.8 however includes a way to break
http://www.scala-lang.org/api/rc/scala/util/control/Breaks.html
An approach that generates the values over a range as we iterate, up to a breaking condition, instead of generating first a whole range and then iterating over it, using Iterator, (inspired in #RexKerr use of Stream)
var sum = 0
for ( i <- Iterator.from(1).takeWhile( _ => sum < 1000) ) sum += i
// import following package
import scala.util.control._
// create a Breaks object as follows
val loop = new Breaks;
// Keep the loop inside breakable as follows
loop.breakable{
// Loop will go here
for(...){
....
// Break will go here
loop.break;
}
}
use Break module
http://www.tutorialspoint.com/scala/scala_break_statement.htm
Just use a while loop:
var (i, sum) = (0, 0)
while (sum < 1000) {
sum += i
i += 1
}
Here is a tail recursive version. Compared to the for-comprehensions it is a bit cryptic, admittedly, but I'd say its functional :)
def run(start:Int) = {
#tailrec
def tr(i:Int, largest:Int):Int = tr1(i, i, largest) match {
case x if i > 1 => tr(i-1, x)
case _ => largest
}
#tailrec
def tr1(i:Int,j:Int, largest:Int):Int = i*j match {
case x if x < largest || j < 2 => largest
case x if x.toString.equals(x.toString.reverse) => tr1(i, j-1, x)
case _ => tr1(i, j-1, largest)
}
tr(start, 0)
}
As you can see, the tr function is the counterpart of the outer for-comprehensions, and tr1 of the inner one. You're welcome if you know a way to optimize my version.
Close to your solution would be this:
var largest = 0
for (i <- 999 to 1 by -1;
j <- i to 1 by -1;
product = i * j;
if (largest <= product && product.toString.reverse.equals (product.toString.reverse.reverse)))
largest = product
println (largest)
The j-iteration is made without a new scope, and the product-generation as well as the condition are done in the for-statement (not a good expression - I don't find a better one). The condition is reversed which is pretty fast for that problem size - maybe you gain something with a break for larger loops.
String.reverse implicitly converts to RichString, which is why I do 2 extra reverses. :) A more mathematical approach might be more elegant.
I am new to Scala, but how about this to avoid throwing exceptions and repeating methods:
object awhile {
def apply(condition: () => Boolean, action: () => breakwhen): Unit = {
while (condition()) {
action() match {
case breakwhen(true) => return ;
case _ => { };
}
}
}
case class breakwhen(break:Boolean);
use it like this:
var i = 0
awhile(() => i < 20, () => {
i = i + 1
breakwhen(i == 5)
});
println(i)
if you don’t want to break:
awhile(() => i < 20, () => {
i = i + 1
breakwhen(false)
});
The third-party breakable package is one possible alternative
https://github.com/erikerlandson/breakable
Example code:
scala> import com.manyangled.breakable._
import com.manyangled.breakable._
scala> val bkb2 = for {
| (x, xLab) <- Stream.from(0).breakable // create breakable sequence with a method
| (y, yLab) <- breakable(Stream.from(0)) // create with a function
| if (x % 2 == 1) continue(xLab) // continue to next in outer "x" loop
| if (y % 2 == 0) continue(yLab) // continue to next in inner "y" loop
| if (x > 10) break(xLab) // break the outer "x" loop
| if (y > x) break(yLab) // break the inner "y" loop
| } yield (x, y)
bkb2: com.manyangled.breakable.Breakable[(Int, Int)] = com.manyangled.breakable.Breakable#34dc53d2
scala> bkb2.toVector
res0: Vector[(Int, Int)] = Vector((2,1), (4,1), (4,3), (6,1), (6,3), (6,5), (8,1), (8,3), (8,5), (8,7), (10,1), (10,3), (10,5), (10,7), (10,9))
import scala.util.control._
object demo_brk_963
{
def main(args: Array[String])
{
var a = 0;
var b = 0;
val numList1 = List(1,2,3,4,5,6,7,8,9,10);
val numList2 = List(11,12,13);
val outer = new Breaks; //object for break
val inner = new Breaks; //object for break
outer.breakable // Outer Block
{
for( a <- numList1)
{
println( "Value of a: " + a);
inner.breakable // Inner Block
{
for( b <- numList2)
{
println( "Value of b: " + b);
if( b == 12 )
{
println( "break-INNER;");
inner.break;
}
}
} // inner breakable
if( a == 6 )
{
println( "break-OUTER;");
outer.break;
}
}
} // outer breakable.
}
}
Basic method to break the loop, using Breaks class.
By declaring the loop as breakable.
Ironically the Scala break in scala.util.control.Breaks is an exception:
def break(): Nothing = { throw breakException }
The best advice is: DO NOT use break, continue and goto! IMO they are the same, bad practice and an evil source of all kind of problems (and hot discussions) and finally "considered be harmful". Code block structured, also in this example breaks are superfluous.
Our Edsger W. Dijkstra† wrote:
The quality of programmers is a decreasing function of the density of go to statements in the programs they produce.
I got a situation like the code below
for(id<-0 to 99) {
try {
var symbol = ctx.read("$.stocks[" + id + "].symbol").toString
var name = ctx.read("$.stocks[" + id + "].name").toString
stocklist(symbol) = name
}catch {
case ex: com.jayway.jsonpath.PathNotFoundException=>{break}
}
}
I am using a java lib and the mechanism is that ctx.read throw a Exception when it can find nothing.
I was trapped in the situation that :I have to break the loop when a Exception was thrown, but scala.util.control.Breaks.break using Exception to break the loop ,and it was in the catch block thus it was caught.
I got ugly way to solve this: do the loop for the first time and get the count of the real length.
and use it for the second loop.
take out break from Scala is not that good,when you are using some java libs.
Clever use of find method for collection will do the trick for you.
var largest = 0
lazy val ij =
for (i <- 999 to 1 by -1; j <- i to 1 by -1) yield (i, j)
val largest_ij = ij.find { case(i,j) =>
val product = i * j
if (product.toString == product.toString.reverse)
largest = largest max product
largest > product
}
println(largest_ij.get)
println(largest)
Below is code to break a loop in a simple way
import scala.util.control.Breaks.break
object RecurringCharacter {
def main(args: Array[String]) {
val str = "nileshshinde";
for (i <- 0 to str.length() - 1) {
for (j <- i + 1 to str.length() - 1) {
if (str(i) == str(j)) {
println("First Repeted Character " + str(i))
break() //break method will exit the loop with an Exception "Exception in thread "main" scala.util.control.BreakControl"
}
}
}
}
}
I don't know how much Scala style has changed in the past 9 years, but I found it interesting that most of the existing answers use vars, or hard to read recursion. The key to exiting early is to use a lazy collection to generate your possible candidates, then check for the condition separately. To generate the products:
val products = for {
i <- (999 to 1 by -1).view
j <- (i to 1 by -1).view
} yield (i*j)
Then to find the first palindrome from that view without generating every combination:
val palindromes = products filter {p => p.toString == p.toString.reverse}
palindromes.head
To find the largest palindrome (although the laziness doesn't buy you much because you have to check the entire list anyway):
palindromes.max
Your original code is actually checking for the first palindrome that is larger than a subsequent product, which is the same as checking for the first palindrome except in a weird boundary condition which I don't think you intended. The products are not strictly monotonically decreasing. For example, 998*998 is greater than 999*997, but appears much later in the loops.
Anyway, the advantage of the separated lazy generation and condition check is you write it pretty much like it is using the entire list, but it only generates as much as you need. You sort of get the best of both worlds.