Coding style - ordering of expressions in blocks in Scala - scala

Since I began programming in Scala, I gravitated towards what seems to be a natural coding style in this language, which is easiest to explain with a simple example:
val a = {
def f1(p : Int) = ...
def f2(p : Int) = ...
f1(12) * f2(100)
}
As you can see, the multiplication of the values, which, if you want to understand the code, is the first operation you should want to familiarize yourself with, is not to be found until the last line. Instead, you need to read through the pieces of the puzzle first (functions f1, f2) before you can see how they're actually arranged. For me, this makes the code harder to read. How are you dealing with this problem - or maybe you don't find it a problem at all?

One interesting approach might be to use the untyped macro proposal in macro-paradise to introduce a where binding, such that:
val a = (f1(12) * f2(100)) where {
def f1(x : Int) = x + 1
def f2(x : Int) = x + 2
}
gets rewritten to your code above. As I understand it, untyped macros would allow the non-existent identifiers f1 and f2 to exist past the pre-macro typecheck. I think the rewrite should be relatively simple, and then the second typecheck would catch any problems. However, I've never actually written any macros, so it's possible there's something about this which would fail!
If it were possible, I think it would be quite a nice form to have (and rewriting would solve problems with execution order) - if I get some time I may have a stab at writing it!
Edit: I've had a go at writing this, and bits of it turn out surprisingly easy. Code is available on github. Unfortunately, the best I can do so far is:
val result = where ( f1(1) * f2(2), {
def f1(x : Int) = x + 1
def f2(x : Int) = x + 2
})
The problem is that Scala's infix operators are just method calls, and so I'd need to have something constructed on the expression (f1(1) * f2(2)) in order to invoke them. But that's the very expression which won't type properly before macro resolution, so I'm not quite sure what to do. Time for a new question, methinks!

Related

No arguments allowed error on implicit class method

I'm trying to cram brush up on Scala for a job I got, and I'm looking into implicit classes. So far they seem quite handy in making code more readable, but I've run into a problem that I can't figure out.
In this code, I'm implementing some common vector operations, and for the most part they seem to be running just fine. However, when I added the norm method, the magn method started throwing errors. My operating script is thus:
import scala.language.postfixOps
import scala.math.sqrt
case class Vector(x: Double, y: Double)
object VMath {
implicit class VectorMath(v1: Vector) {
def dot(v2: Vector): Double = v1.x * v2.x + v1.y * v2.y
def cross(v2: Vector): Double = v1.x * v2.y - v1.y * v2.x
def magn(): Double = sqrt(v1.x * v1.x + v1.y * v1.y)
def norm(): Vector = Vector(v1.x / magn, v1.y / magn)
}
}
import VMath._
val a = Vector(1.0, 2.0)
val b = Vector(3.0, 4.0)
a dot b
a cross b
a magn
a norm
Whenever I run this code, the line a magn throws an error that reads
no arguments allowed for nullary method magn: ()Double
It had no problem running before I implemented the norm method, and it has no problems within the norm method. I'm not sure if this is due to my misunderstanding of how Scala itself works, how postfixObs works, how implicit classes work, how single line methods work, or if it's just some stupid typo that I'm missing, but this has got me tearing my hair out. (And I happen to like my hair, so...)
My code can be tested and the problem recreated on Scastie: https://scastie.scala-lang.org/0jvrx4lYQwauBpN6IZtSPA
Postfix notation (dot-less) can be used when the method takes no argument, but you have to help the compiler figure it out.
a magn
a norm;
A blank line, or a semicolon, tells the compiler to stop looking for the argument to pass to the method. It's not coming.
It's usually better to reserve dot-less notation for only the simplest, most obvious, declarations (with all 3 pieces).
Seems like compiler got confused and treated a in the last line as argument to magn method. There is nothing wrong with your implementation of norm method.
Possible fixes
add dots -> a.magn
terminate line with semicolon a magn;
introduce empty paranthesis a magn()

Are Scala closures as flexible as C++ lambdas?

I know the question seems a bit heretical. Indeed, having much appreciated lambdas in C++11, I was quite thrilled to learn a language which was built to support them from the beginning rather than as a contrived addition.
However, I cannot figure out how to do with Scala all I can do with C++11 lambdas.
Suppose I want to make a function which adds to a number passed as a parameter some value contained in a variable a. In C++, I can do both
int a = 5;
auto lambdaVal = [ a](int par) { return par + a; };
auto lambdaRef = [&a](int par) { return par + a; };
Now, if I change a, the second version will change its behavior; but the first will keep adding 5.
In Scala, if I do this
var a = 5
val lambdaOnly = (par:Int) => par + a
I essentially get the lambdaRef model: changing a will immediately change what the function does.
(which seems somewhat specious to me given that this time a isn't even mentioned in the declaration of the lambda, only in its code. But let it be)
Am I missing the way to obtain lambdaVal? Or do I have to first copy a to a val to be free to modify it afterwards without side effects?
The a in the function definition refers the variable a. If you want to use the current value of a when the lambda has been created, you have to copy the value like this:
val lambdaConst = {
val aNow = a
(par:Int) => par + aNow
}

Does return break referential transparency?

I was reading the description of the Scala WartRemover tool, and was confused by one of the points they had. The description said this:
return breaks referential transparency. Refactor to terminate
computations in a safe way.
// Won't compile: return is disabled
def foo(n:Int): Int = return n + 1
def foo(ns: List[Int]): Any = ns.map(n => return n + 1)
This doesn't make any sense to me, and both of the examples look referentially transparent. Is there some way in which the return keyword makes it any more likely for a function to break referential transparency? Am I just completely misunderstanding their point?
At it's core, referentially transparency is about evaluating expressions. Fundamentally, it says that if you evaluate an expression in a context, it will evaluate to the same value if you evaluate it in any identical context.
Except that "return" statements don't evaluate to anything at all. They cause the current call of the enclosing method to evaluate to something. There's no way that fits the concept of referential transparency. The "throw" statement has a similar problem.
For the examples, the first one
def foo(n:Int): Int = return n + 1
is benign but verbose and non-idiomatic. The second one
def foo(ns: List[Int]): Any = ns.map(n => return n + 1)
is much more problematic. If passed the empty list, it returns the empty list. If passed a non empty list, it returns the value of the head of the list plus 1.

Scala while loop returns Unit all the time

I have the following code, but I can't get it to work. As soon as I place a while loop inside the case, it's returning a unit, no matter what I change within the brackets.
case While(c, body) =>
while (true) {
eval(Num(1))
}
}
How can I make this while loop return a non-Unit type?
I tried adding brackets around my while condition, but still it doesn't do what it's supposed to.
Any pointers?
Update
A little more background information since I didn't really explain what the code should do, which seems to be handy if I want to receive some help;
I have defined a eval(exp : Exp). This will evaluate a function.
Exp is an abstract class. Extended by several classes like Plus, Minus (few more basic operations) and a IfThenElse(cond : Exp, then : Exp, else : Exp). Last but not least, there's the While(cond: Exp, body: Exp).
Example of how it should be used;
eval(Plus(Num(1),Num(4)) would result in NumValue(5). (Evaluation of Num(v : Value) results in NumValue(v). NumValue extends Value, which is another abstract class).
eval(While(Lt(Num(1),Var("n")), Plus(Num(1), Var("n"))))
Lt(a : Exp, b : Exp) returns NumValue(1) if a < b.
It's probably clear from the other answer that Scala while loops always return Unit. What's nice about Scala is that if it doesn't do what you want, you can always extend it.
Here is the definition of a while-like construct that returns the result of the last iteration (it will throw an exception if the loop is never entered):
def whiley[T](cond : =>Boolean)(body : =>T) : T = {
#scala.annotation.tailrec
def loop(previous : T) : T = if(cond) loop(body) else previous
if(cond) loop(body) else throw new Exception("Loop must be entered at least once.")
}
...and you can then use it as a while. (In fact, the #tailrec annotation will make it compile into the exact same thing as a while loop.)
var x = 10
val atExit = whiley(x > 0) {
val squared = x * x
println(x)
x -= 1
squared
}
println("The last time x was printed, its square was : " + atExit)
(Note that I'm not claiming the construct is useful.)
Which iteration would you expect this loop to return? If you want a Seq of the results of all iterations, use a for expression (also called for comprehension). If you want just the last one, create a var outside the loop, set its value on each iteration, and return that var after the loop. (Also look into other looping constructs that are implemented as functions on different types of collections, like foldLeft and foldRight, which have their own interesting behaviors as far as return value goes.) The Scala while loop returns Unit because there's no sensible one size fits all answer to this question.
(By the way, there's no way for the compiler to know this, but the loop you wrote will never return. If the compiler could theoretically be smart enough to figure out that while(true) never terminates, then the expected return type would be Nothing.)
The only purpose of a while loop is to execute a side-effect. Or put another way, it will always evaluate to Unit.
If you want something meaningful back, why don't you consider using an if-else-expression or a for-expression?
As everyone else and their mothers said, while loops do not return values in Scala. What no one seems to have mentioned is that there's a reason for that: performance.
Returning a value has an impact on performance, so the compiler would have to be smart about when you do need that return value, and when you don't. There are cases where that can be trivially done, but there are complex cases as well. The compiler would have to be smarter, which means it would be slower and more complex. The cost was deemed not worth the benefit.
Now, there are two looping constructs in Scala (all the others are based on these two): while loops and recursion. Scala can optimize tail recursion, and the result is often faster than while loops. Or, otherwise, you can use while loops and get the result back through side effects.

Scala closures on wikipedia

Found the following snippet on the Closure page on wikipedia
//# Return a list of all books with at least 'threshold' copies sold.
def bestSellingBooks(threshold: Int) = bookList.filter(book => book.sales >= threshold)
//# or
def bestSellingBooks(threshold: Int) = bookList.filter(_.sales >= threshold)
Correct me if I'm wrong, but this isn't a closure? It is a function literal, an anynomous function, a lambda function, but not a closure?
Well... if you want to be technical, this is a function literal which is translated at runtime into a closure, closing the open terms (binding them to a val/var in the scope of the function literal). Also, in the context of this function literal (_.sales >= threshold), threshold is a free variable, as the function literal itself doesn't give it any meaning. By itself, _.sales >= threshold is an open term At runtime, it is bound to the local variable of the function, each time the function is called.
Take this function for example, generating closures:
def makeIncrementer(inc: Int): (Int => Int) = (x: Int) => x + inc
At runtime, the following code produces 3 closures. It's also interesting to note that b and c are not the same closure (b == c gives false).
val a = makeIncrementer(10)
val b = makeIncrementer(20)
val c = makeIncrementer(20)
I still think the example given on wikipedia is a good one, albeit not quite covering the whole story. It's quite hard giving an example of actual closures by the strictest definition without actually a memory dump of a program running. It's the same with the class-object relation. You usually give an example of an object by defining a class Foo { ... and then instantiating it with val f = new Foo, saying that f is the object.
-- Flaviu Cipcigan
Notes:
Reference: Programming in Scala, Martin Odersky, Lex Spoon, Bill Venners
Code compiled with Scala version 2.7.5.final running on Java 1.6.0_14.
I'm not entirely sure, but I think you're right. Doesn't a closure require state (I guess free variables...)?
Or maybe the bookList is the free variable?
As far as I understand, this is a closure that contains a formal parameter, threshold and context variable, bookList, from the enclosing scope. So the return value(List[Any]) of the function may change while applying the filter predicate function. It is varying based on the elements of List(bookList) variable from the context.