Scala: How to make a closure not to see changes in its free variable? - scala

In the following code snippet, closure foo see the changes made in x as it should in scala. However, how can I make local variable y in foo hold value of x permanently and not see changes?
scala> var x = 10
x: Int = 10
scala> val foo = (a:Int) => {val y = x; a + y}
foo: Int => Int = <function1>
scala> foo(3)
res1: Int = 13
scala> x = 5
x: Int = 5
scala> foo(3) //see changes made in x. But how can I make closure not to see changes made on x?
res2: Int = 8

You could do something like this:
val foo = ((x:Int) => (a:Int) => {val y = x; a + y})(x)
In this case, x is bound in foo.
What you are doing is an example of closure.

scala> var x = 10
x: Int = 10
scala> val foo = { val y = x; (a: Int) => a + y }
foo: Int => Int = $$Lambda$1027/1344946518#5416f8db
scala> foo(3)
res0: Int = 13
scala> x = 5
x: Int = 5
scala> foo(3)
res1: Int = 13

Related

How to access the replaceAllIn() counter?

I am using
val str2 = regex.replaceAllIn(str1, "other")
and need to count the number of replaces... There are a way retrieve the value of the internal replaceAllIn counter?
PS: this is usual in other languages (example), so I am supposing that Scala offer similar thing.
scala> val r = "x".r
r: scala.util.matching.Regex = x
scala> var i = 0
i: Int = 0
scala> r.replaceAllIn("xooxxox", m => { i += 1 ; "X" })
res0: String = XooXXoX
scala> i
res1: Int = 4
will do appendReplacement under the hood.
Takes another step but you could findAllIn and count the number found. Then do replaceAllIn.
scala> "foo".r.findAllIn("barbazfoobazfoo").size
res7: Int = 2

How to use previous expression's result in Scala REPL?

// when in Scala REPL
scala> 1
res0: Int = 1
How can I reuse an expression's result in another expression?
For example:
scala> 1
res0: Int = 1
scala> the_previous_expression + 1
// = 2
You can reuse the previous expression's result by looking its REPL output on the next line, the word starting with res.
// when in Scala REPL
scala> 1
res0: Int = 1 // <-- res0 is the handle that you can use
For example:
scala> 1
res0: Int = 1
scala> res0 + 1
res1: Int = 2
scala> res1 + 1
res2: Int = 3
// and so on
You can also use it with others:
scala> () => "hey!" // anonymous function
res0: () => String = $$Lambda$1104/1658578510#6cff61fc
scala> res0()
res1: String = hey

sequence of scala function return methods

I am new to scala and learning scala.
scala> def first(x: Int)= (y: Int) => x + y
first: (x: Int)Int => Int
scala> val second= first(1)
second: Int => Int = <function1>
scala> second(2)
res8: Int = 3
I want to understand the above function, first 1 is passed as an argument and returns second function it does nothing , just stores the value of x=1 , then the second val, which represents the second function is called as 2, then the value of Y is stored as 2 , then it called the return => x + y,
which evaluates to 1+2 and gives 3 as result.
Please let me know if my understanding is correct.
If anyone can add something to it or correct if I am wrong.
Thanks and Regards,
scala> def first(x: Int)= (y: Int) => x + y // 1
first: (x: Int)Int => Int
scala> val second= first(1) // 2
second: Int => Int = <function1>
scala> second(2) // 3
res8: Int = 3
In case 1, you have created a function called first which accepts an integer and returns a function which accepts an integer and adds it to integer you passed to first.
In case 2, you apply 1 to the first function to return a function which accepts an integer and adds 1 to it. You have 'labelled' this function second. This is equivalent to (y : Int) => 1 + y.
In case 3, you apply 2 to the second function which returns 3 as expected.

One argument referencing another in the argument list

Occasionally, I encounter one argument wanting to reference another. For instance,
def monitor(time: Double, f: Double => Double, resolution: Double = time / 10) = {...}
Note that resolution refers to time. Are there languages where this is possible? Is it possible in Scala?
It is somewhat possible in Scala, but you have to curry the parameters:
def monitor(time: Double, f: Double => Double)(resolution: Double = time / 10)
You cannot do it in the way the question is posed.
I don't know any langage where this construction is possible, but a simple workaround is not difficult to find.
In scala, something like this is possible :
scala> def f(i : Int, j : Option[Int] = None) : Int = {
| val k = j.getOrElse(i * 2)
| i + k
| }
f: (i: Int, j: Option[Int])Int
scala> f(1)
res0: Int = 3
scala> f(1, Some(2))
res1: Int = 3
In scala, you can also make something like this :
scala> def g(i : Int)(j : Int = i * 2) = i + j
g: (i: Int)(j: Int)Int
scala> g(2)(5)
res6: Int = 7
scala> g(2)()
res7: Int = 6

fully applying functions in Scala, shorthand notation impossible?

Is there a way to declare a fully-applied function without a full new lambda?
scala> val F = (x: Int) => math.pow(x,2)
F: Int => Double = <function1>
scala> val G = F(3)
G: Double = 9.0
How can I declare it such that G is an:
() => Double = <function0>
Without doing this:
scala> val G = () => F(3)
G: () => Double = <function0>
? The _ notation doesn't seem to do the trick:
scala> val G = F(3) _
<console>:8: error: _ must follow method; cannot follow Double
val G = F(3) _
There is no way. The shortest form is what you came up with, i.e., () => F(3).