I am trying to figure out if Scala programming language has a way of Aliasing(presence of two or more distinct referencing methods for the same memory location).
I can see example of type aliasing such as "x: (Int, String) = (1,one)". So x has two different types but do they share same memory?
I would greatly appreciate if anyone could give more explanation.
If you want one "variable" to track another, you could do something like this.
scala> var x = 5 // create a variable
x: Int = 5
scala> def y = x // keep track of x
y: Int
scala> x = 9 // change x
x: Int = 9
scala> y // yep, y changes too
res1: Int = 9
This isn't a true alias. You can't modify y and see the change in x. A def is simply re-evaluated every time it is invoked, so every time you query y, it re-examines x for the current value.
Note that this type of thing is not considered good Scala practice. In Functional Programming you want to avoid data structures that maintain state, i.e. don't use a var if you don't have to, and good Scala programmers almost never have to.
Related
I'm learning functional programming partially by reading the book Functional Programming in Scala a.k.a. The Red Book and I've run into my first real blocker. In Chapter 6, The book uses the example of a random number generator to illustrate how to change state by using side effects. Then the book goes on to demonstrate the patterns you would typically encounter as well as some of the tangents you might take in making a functional stateful api. My problem comes when trying to understand the following code:
type Rand[+A] = RNG => (A, RNG)
def map[A, B](s: Rand[A])(f: A => B): Rand[B] =
rng => {
val (nxt, nxtrng) = s(rng)
(f(nxt), nxtrng)
}
def nonNegativeLessThan(n: Int): Rand[Int] =
map(nonNegativeIntv2) { i =>
val mod = i % n
if (i + (n - 1) - mod >= 0) mod else nonNegativeLessThan(n)(???)
}
I hope this is enough context to get an idea what the code does. This is coming directly from the book on page 86. How does the if statement for method nonNegativeLessThan filters out values of i that are greater than the largest multiple of n in a 32 bit integer? Doesn't the recursive call in the else clause return a value of type Rand[Int]? In general I'm confused about what's going on in the code that is bolded. This is a pretty good book so I'm happy with how things are going so far and I feel I've learned a lot about functional programming. My apologies if this question is ill formed and if there is an issue with the formatting. This is my first post on stack overflow! Thank you to those who take a look at this and I hope it helps someone who has the same problem.
How does the if statement for method nonNegativeLessThan filters out values of i that are greater than the largest multiple of n in a 32 bit integer?
If i is greater than the largest multiple of n, then i + (n - 1) - mod will overflow and yield a negative number. The subsequent >= 0 is then false.
Doesn't the recursive call in the else clause return a value of type Rand[Int]?
Well, nonNegativeLessThan(n) is indeed of type Rand[Int]. However it says nonNegativeLessThan(n)(???), that is, it applies nonNegativeLessThan to n, and then it applies the resulting value (of type Rand[Int], which is a function type) to ???, and that yields an Int. Or rather it would do that if ??? ever yielded real value, which it doesn't.
The problem here is that you would have to pass the state of the RNG instead of ???, but the map function doesn't let you access that state. You'll need flatMap to solve this – presumably that's what the book is going to discuss next.
Imagine that you have a new domain of a set of integers, for example 0 to 11. The Rand type represents an aleatory number in that domain, but this type can not be skewed. That means that there can not be numbers that have a greater probability of being generated that others.
If you want to generate a number that is positive and less than four, you can use the map function of the Rand type, that allows to transform the result of a state action. First, it generates a nonnegative number and transform the result, via the map, applying the anonymous function: _ % n to obtain a number less than n.
def nonNegativeLessThan(n: Int): Rand[Int] =
map(nonNegativeInt) { _ % n }
It uses the modulo operation:
scala> 1 % 4
res0: Int = 1
scala> 2 % 4
res1: Int = 2
scala> 3 % 4
res2: Int = 3
scala> 4 % 4
res3: Int = 0
scala> 5 % 4
res4: Int = 1
scala> 6 % 4
res5: Int = 2
scala> 7 % 4
res6: Int = 3
scala> 8 % 4
res7: Int = 0
scala> 9 % 4
res8: Int = 1
scala> 10 % 4
res9: Int = 2
As you can see, the largest multiple of 4 in this domain is 8, so if the non-negative number that is generated is 9 or 10, we have a problem. The probability of having a 1 or 2 is greater than having a 3 or a 0. And for that reason, the other implementation detects that the number which is first generated as a result of the nonnegativeInt is not major than the largest multiple of n in a specific domain, the Int32 numbers domain in the book, to have a non- biased generator.
And yes, that book is amazing.
I can use closure to define function like this:
def product(x: Int) = (y: Int) => x * y
val productBy3 = product(3)
println(productBy3(6)) // 18
OR, using currying:
def curriedProduct(x: Int)(y: Int) = x * y
val productBy3 = curriedProduct(3)_
println(productBy3(6)) // 18
Any advantage/disadvantage one approach has over other?
The first is an example of a method returning a function. The second is an example of a method with multiple parameter lists.
The way you use them, there is no difference.
When called as product(3)(6), the second may be a bit faster, but not to an extent that would normally be a concern.
I would use the first form when the expected way to call it would be with product(3), and use the second form if the normal way to call it would be product(3)(6).
Lastly, I'd like to suggest the possibility of
def product(i: Int, j: Int) = i * j
val productBy3 = product(3, _)
println(productBy3(6)) //18
I don't really see any upsides of using the second form instead of either this alternative or the first alternative in this situation. Using multiple parameter lists may help type inference in scala 2 (see https://docs.scala-lang.org/tour/multiple-parameter-lists.html), but there is no problematic inference here anyway.
For most languages I wouldn't ask "why did they do X like this?" as it's generally opinion based.
For languages like C++ the usual answer is to quote some bit of some specification and all one can say is that someone probably thought long and hard before making a particular choice (but could have made a different choice).
Scala is different - often the answer is to point out that you can think of X in terms of some simpler structures Y and Z and so the formulation of X as it is makes sense when seen in this context.
So given that I'll ask why Scala allows a definitions that introduces multiple names and evaluates a given expression once for each name?
If you asked a Java programmer to guess what would happen here, they'd probably guess wrong:
var x, y, z = 3
I.e. they'd guess only z got assigned a value.
If you explained val and then told them the following was legal:
val x, y, z = 3
Then they'd probably guess more was afoot as clearly x and y must have values after this line as they cannot be assigned a different value later.
They might assume that x and y took a default values for their type, e.g. 0 for integers, but as there are no explicit types here that'd be a leap.
They might assume that it's handled as:
val z = 3
val x = z
val y = z
It doesn't really matter when the expression to the left of the = produces a primitive value or an immutable object. But the following might give them cause to wonder:
val x, y, z = new StringBuilder
Why would anyone want to introduce three names for the same StringBuilder instance?
And if you showed them the following they might, from the construction, guess that something odder was up before they even ran the code:
var i = 0
def f: Int = {
i += 1
println(i)
i
}
val x, y, z = f
One eventually realizes that the expression that appears to only be associated with z is actually evaluated once for each name, i.e. the above is equivalent to:
val x = f
val y = f
val z = f
So is it even interesting to talk about what programmers who are used to another language might think?
Well most people come to a language like Scala from somewhere else so to a degree constructions that are likely to be confusing should be avoided unless there's a good reason for them.
At first glance this feature doesn't seem to offer much, it avoids you having to repeat yourself, but to add this piece of rather confusing syntactical sugar for such a small gain seems odd.
So is there some circumstance in which it brings real benefit? Or is there no real gain here but e.g. we maintain some kind of logical consistency with some broader pattern established elsewhere?
There is one case where this surprising feature is used: when defining a scala.Enumeration:
object Weekday extends scala.Enumeration {
val Monday, Tuesday, Wednesday, Thursday, Friday = Value
}
which calls Value (a def inherited from Enumeration) 5 times, once for each field of the enumeration. Effectively this allocates a new instance of Enumeration#Value for each field, which is obviously what you need for an enumeration to be useful.
Without this multi-assignment feature, you would have to write:
object Weekday extends scala.Enumeration {
val Monday = Value
val Tuesday = Value
val Wednesday = Value
val Thursday = Value
val Friday = Value
}
I have never seen the multi-assignment feature used anywhere else but in an Enumeration declaration.
Whether or not this is good idea in terms of language design is a subjective question, and SO is not the right place to discuss it.
You have basically answered your own question. The choice is between val x, y, z = someComplexExpression meaning
val z = someComplexExpression
val y = z
val x = z
or
val x = someComplexExpression
val y = someComplexExpression
val z = someComplexExpression
or not being allowed at all. The first is a bad choice for two reasons:
You mention the first: you don't generally need to give multiple names to the same instance.
If you choose the first, you have to duplicate the someComplexExpression every time you need the second, or to extract it to a method. If you choose the second, writing the first when you need it (despite point 1) is trivial:
val z = someComplexExpression
val x, y = z
Not allowing it would be possible. I don't think I've ever actually seen it used [before seeing your comment]. But removing it once it's allowed is a bad idea.
Obviously var x, y, z = ... needs to be consistent with this.
I am new to Scala and I am still trying to get used to its syntax and rules.
I have a method that takes two inputs and returns a list with the numbers in between, excluding the last number. For example:
int a = 2
int b = 5
The list would be {2,3,4}
I have a method that creates a list but also account for the last digit.
def fromTo(low:Int,high:Int): List[Int] = {
if(low == high)
lo::Nil
else
lo::fromTo(low+1,hi)
}
I tried creating a new variable but that did not work. Any ideas on how to make that last digit not be part of the list?
Think about your base case. What happens if you call fromTo(a,a) for some integer a.
Maybe a bit off topic, but you're also assuming that low <= high might want to look into that as well.
I'm not sure if you are specifically trying to do this with a recursive call but if all you really want is the list of numbers from X to Y excluding Y, you can just do the following:
scala> (2 until 5).toList
res3: List[Int] = List(2, 3, 4)
In Scala, I can define a function with two parameter lists.
def myAdd(x :Int)(y :Int) = x + y
This makes it easy to define a partially applied function.
val plusFive = myAdd(5) _
But, I can accomplish something similar by defining and returning a nested function.
def myOtherAdd(x :Int) = {
def f(y :Int) = x + y
f _
}
Cosmetically, I've moved the underscore, but this still feels like currying.
val otherPlusFive = myOtherAdd(5)
What criteria should I use to prefer one approach over the other?
There are at least four ways to accomplish the same thing:
def myAddA(x: Int, y: Int) = x + y
val plusFiveA: Int => Int = myAddA(5,_)
def myAddB(x: Int)(y : Int) = x + y
val plusFiveB = myAddB(5) _
def myAddC(x: Int) = (y: Int) => x + y
val plusFiveC = myAddC(5)
def myAddD(x: Int) = {
def innerD(y: Int) = x + y
innerD _
}
val plusFiveD = myAddD(5)
You might want to know which is most efficient or which is the best style (for some non-performance based measure of best).
As far as efficiency goes, it turns out that all four are essentially equivalent. The first two cases actually emit exactly the same bytecode; the JVM doesn't know anything about multiple parameter lists, so once the compiler figures it out (you need to help it with a type annotation on the case A), it's all the same under the hood. The third case is also extremely close, but since it promises up front to return a function and specifies it on the spot, it can avoid one internal field. The fourth case is pretty much the same as the first two in terms of work done; it just does the conversion to Function1 inside the method instead of outside.
In terms of style, I suggest that B and C are the best ways to go, depending on what you're doing. If your primary use case is to create a function, not to call in-place with both parameter lists, then use C, because it tells you what it's going to do. (This version is also particularly familiar to people coming from Haskell, for instance.) On the other hand, if you are mostly going to call it in place but will only occasionally curry it, then use B. Again, it says more clearly what it's expected to do.
You could also do this:
def yetAnotherAdd(x: Int) = x + (_: Int)
You should choose the API based on intention. The main reason in Scala to have multiple parameter lists is to help type inference. For instance:
def f[A](x: A)(f: A => A) = ...
f(5)(_ + 5)
One can also use it to have multiple varargs, but I have never seen code like that. And, of course, there's the need for the implicit parameter list, but that's pretty much another matter.
Now, there are many ways you can have functions returning functions, which is pretty much what currying does. You should use them if the API should be thought of as a function which returns a function.
I think it is difficult to get any more precise than this.
Another benefit of having a method return a function directly (instead of using partial application) is that it leads to much cleaner code when using infix notation, allowing you to avoid a bucketload of parentheses and underscores in more complex expressions.
Consider:
val list = List(1,2,3,4)
def add1(a: Int)(b: Int) = a + b
list map { add1(5) _ }
//versus
def add2(a: Int) = a + (_: Int)
list map add2(5)