unrecognizable code in scala Predef object - scala

Can someone please explain the following code in Predef object? Thanks.
scala.`package` // to force scala package object to be seen.
scala.collection.immutable.List // to force Nil, :: to be seen.

(Link). I can only guess. When you use a singleton object as expression, this has the same effect as forcing the evaluation of a lazy val, in other words it will run the object's body if it wasn't yet initialised.
For example:
object Foo {
println("Foo is launching rockets...")
}
Now when you write just
Foo // prints `Foo is launching rockets...`
this enforces the evaluation of the contents of Foo.
So my guess is that in Predef this just makes sure that certain things in the scala package object and in List are initialised. Very unlikely something you would bother as a user.

The accepted answer has to be wrong.
Update: The ML provided a couple of helpful links to issues, without saying whether the problem is only runtime dependencies between modules or also compiler-internal or similar.
Predef is imported at compile time to make various definitions available when your source file is compiled. (Update: but still carries some value definitions, and not all its methods are inlined. And in any case, even an inlined usage, of assert for example, will incur a reference to Predef$.MODULE$, because of side-effects at initialization, see below.)
You can turn off that behavior with -Yno-predef. For example,
apm#mara:~/goof$ scala -Yno-predef
Welcome to Scala version 2.10.3 (OpenJDK 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> "a" -> 1
<console>:8: error: value -> is not a member of String
"a" -> 1
^
It has nothing to do with runtime evaluation. Otherwise, everything in Predef and everything it referenced would get loaded before your program got a chance to run.
(Update: yeah, well, guess what.)
In Scala, import is not like #include.
Useful exercise:
scala> :javap -prv scala.Predef$
private scala.Predef$();
flags: ACC_PRIVATE
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: invokespecial #520 // Method scala/LowPriorityImplicits."<init>":()V
4: aload_0
5: putstatic #522 // Field MODULE$:Lscala/Predef$;
8: aload_0
9: invokestatic #526 // Method scala/DeprecatedPredef$class.$init$:(Lscala/Predef$;)V
12: getstatic #531 // Field scala/package$.MODULE$:Lscala/package$;
15: pop
16: getstatic #536 // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
19: pop
20: aload_0
21: getstatic #540 // Field scala/collection/immutable/Map$.MODULE$:Lscala/collection/immutable/Map$;
24: putfield #151 // Field Map:Lscala/collection/immutable/Map$;
// etc, etc
No doubt my understanding is incomplete.

Related

How to configure `sbt` to not display warnings "Warning private default argument in object * is never used"

I have a scala compiler 2.12.11 and compiler prints some warnings, like:
private default argument in class SomeClass is never used
while as it is used.
I have seen a Scala 2.12.2 emits a ton of useless "Warning: parameter value ... in method ... is never used" warnings. How to get rid of them? however it doesn't help me, as it is not possible to negate params.
Can you help me to surpress this warning, however saving another unused warnings? Currently, I have -Xlint option.
Instead of -Xlint which is a batch, you can turn on specific options manually. For instant in 2.13 I can print available options like this:
scalac -Xlint:help
Enable recommended warnings
adapted-args An argument list was modified to match the receiver.
nullary-unit `def f: Unit` looks like an accessor; add parens to look side-effecting.
inaccessible Warn about inaccessible types in method signatures.
infer-any A type argument was inferred as Any.
missing-interpolator A string literal appears to be missing an interpolator id.
doc-detached When running scaladoc, warn if a doc comment is discarded.
private-shadow A private field (or class parameter) shadows a superclass field.
type-parameter-shadow A local type parameter shadows a type already in scope.
poly-implicit-overload Parameterized overloaded implicit methods are not visible as view bounds.
option-implicit Option.apply used an implicit view.
delayedinit-select Selecting member of DelayedInit.
package-object-classes Class or object defined in package object.
stars-align In a pattern, a sequence wildcard `_*` should match all of a repeated parameter.
strict-unsealed-patmat Pattern match on an unsealed class without a catch-all.
constant Evaluation of a constant arithmetic expression resulted in an error.
unused Enable -Wunused:imports,privates,locals,implicits,nowarn.
nonlocal-return A return statement used an exception for flow control.
implicit-not-found Check #implicitNotFound and #implicitAmbiguous messages.
serial #SerialVersionUID on traits and non-serializable classes.
valpattern Enable pattern checks in val definitions.
eta-zero Usage `f` of parameterless `def f()` resulted in eta-expansion, not empty application `f()`.
eta-sam The Java-defined target interface for eta-expansion was not annotated #FunctionalInterface.
deprecation Enable -deprecation and also check #deprecated annotations.
byname-implicit Block adapted by implicit with by-name parameter.
recurse-with-default Recursive call used default argument.
unit-special Warn for specialization of Unit in parameter position.
multiarg-infix Infix operator was defined or used with multiarg operand.
implicit-recursion Implicit resolves to an enclosing definition.
Default: All choices are enabled by default.
so I could e.g. enable -Xlint:inaccessible -Xlint:adapted-args -Wunused:privates,locales or whatever I want instead of everything. For 2.12 this list would be different. (You can also check scalac -X, scalac -Y and scalac -W).
An alternative is to enable warnings and suppress them when you "breaking" something consciously. For unused you have #scala.annotation.unused, for other warnings in 2.12 and before there is silencer plugin and since 2.13 there is #scala.annotation.nowarn annotation.

Understanding the Idea behind Tail Recursion in Scala

I come from a object oriented background, where I primarily wrote applications in Java. I recently started to explore more on Scala and I have been reading some text. I thus came across something called tail recursion. I understood how to write tail recursive methods.
For example - To add the elements in a List (Of course this could be done using reduce method) but for the sake of understanding, I wrote a tail recursive method:
#scala.annotation.tailrec
def sum(l: List[Int], acc: Int): Int = l match {
case Nil => acc
case x :: xs => sum(xs, acc + x)
}
How is this recursion handled internally by the Scala run time?
How is this recursion handled internally by the Scala run time?
It isn't. It is handled by the compiler at compile time.
Tail-recursion is equivalent to a while loop. So, a tail-recursive method can be compiled to a while loop, or, more precisely, it can be compiled the same way a while loop is compiled. Of course, how exactly it is compiled depends on the compiler being used.
There are currently three major implementations of Scala, these are Scala-native (a compiler that targets native machine code with its own runtime), Scala.js (a compiler that targets the ECMAScript platform, sitting on top of the ECMAScript runtime), and the JVM implementation Scala which confusingly is also called "Scala" like the language (which targets the JVM platform and uses the JVM runtime). There used to be a Scala.NET, but that is no longer actively maintained.
I will focus on Scala-JVM in this answer.
I'll use a slightly different example than yours, because the encoding of pattern matching is actually fairly complex. Let's start with the simplest possible tail-recursive function there is:
def foo(): Unit = foo()
This gets compiled by Scala-JVM to the following JVM bytecode:
public void foo()
0: goto 0
Remember how I said above that tail-recursion is equivalent to looping? Well, the JVM doesn't have loops, it only has GOTO. This is exactly the same as a while loop:
def bar(): Unit = while (true) {}
Gets compiled to:
public void bar()
0: goto 0
And for a slightly more interesting example:
def baz(n: Int): Int = if (n <= 0) n else baz(n-1)
gets compiled to:
public int baz(int);
0: iload_1
1: iconst_0
2: if_icmpgt 9
5: iload_1
6: goto 16
9: iload_1
10: iconst_1
11: isub
12: istore_1
13: goto 0
16: ireturn
As you can see, it is just a while loop.

Why are FunctionN types in Scala created as a subtype of AnyRef, not AnyVal?

If I understand correctly, under the JVM, every time I use a lambda expression, an Object has to be created.
Why the overhead? Why did the Scala creators choose to extend AnyRef instead of AnyVal when designing FunctionN types? I mean, they don't have any real 'values' in them by themselves, so shouldn't it be possible for functions to be value objects with an underlying Unit representation (or a long containing some hash for equality checking or whatever)? I can imagine not allocating an object per every lambda can lead to performance boosts in some codebases.
One obvious disadvantage that comes to my mind of extending AnyVal is that it would prohibit subclassing function types. Maybe that alone would be sufficient to be not extending AnyVal, but what other reasons can there be?
--Edit
I understand that functions need to close over other variables, but I think it would be more natural to model it as arguments to the apply method, not field members of FunctionN objects (thus removing the necessity to have a java.lang.Object on this part) -- after all, isn't what variables are closed over all known at compile time?
--Edit again
I found out about it; what I had in mind was 'lambda lifting'.
The only ways to call a method are the bytecode operations invokevirtual (virtual dispatch on class), invokeinterface (same, but on interfaces), invokespecial (invoke exactly the given method, ignoring virtual lookup. Used for private, super, and new.), and invokestatic (summon unicorns call static method). invokespecial is out, because calling exactly some function is the antithesis of abstracting over a function. invokestatic is out, too, because it's essentially an invokespecial clone that doesn't need a this argument. invokevirtual and invokeinterface are similar enough for our purposes to be considered the same.
There's no way to pass a plain function pointer like you might see in C, and even if you could, you could never call it, as there is no instruction that can jump to an arbitrary point in code. (All jump targets inside a method are restricted to that method, and all references to the outside boil down to strings. (The JVM, of course, is free to optimize that representation once a file is loaded.))
In order to invoke a method with either instruction, the JVM must look up the method inside the target object's virtual dispatch table. If you tried to dummy out the object with () (AnyVal subclasses didn't exist until 2.10, but let's suspend our disbelief), then the JVM would get horribly confused when you tried to call a (presumably interesting) method on something that's as close to "featureless blob" as you can get.
Also remember that an object's methods are totally determined by its class. If a.getClass == b.getClass, then a and b have the exact same methods, code and all. In order to get around this, we need to create subclasses of the FunctionN traits, such that each subclass represents one function, and each instance of each class contains a reference to its class which contains a reference to the code associated with that function. Even with invokedynamic, this is still true, as the LambdaMetaFactory's current implementation creates an inner class at runtime.
Finally, the assumption that functions need no state is false, as #Oleg points out. Closures need to keep references to their environment, and that is only possible with an object.

Scala illegal start of simple expression with postfix function

I am playing around with calling external command from Scala. Here is a stripped out example of what I am working on:
import scala.sys.process._
object Testing {
def main(args: Array[String]) {
val command = "ls"
val result = command!
if (result != 0) { // <---- illegal start of simple expression
println("Error")
return
}
}
}
I am getting a compile error: illegal start of simple expression for the line with the if statement. I can fix it with a new line:
val result = command!
// Add a line
if (result != 0) {
My suspicion is that it has something to do with the ! postfix function, but it was my understanding that superfluous lines/whitespaces shouldn't make a difference to the compiler.
You need to explicitly enable postfix expressions:
1) Importing the flag locally: import scala.language.postfixOps
2) or adding the flag to the project itself: scalacOptions += "-language:postfixOps"
The above link in the comment from #Łukasz contains lots of info about this feature. Also, see http://docs.scala-lang.org/style/method-invocation.html in the "Suffix Notation" section for your exact use case.
EDIT: maybe it was not clear enough, but as #Łukasz pointed in comments, importing/enabling postfix expressions doesn't make your code compile. It just avoids the compiler warning. Your code won't compile because the semicolons are optional and the compiler is treating the ! operator as infix, and thus taking elements from the next line for the expressions. This is exactly what the documentation in the link above states with exactly this same example:
This style is unsafe, and should not be used. Since semicolons are
optional, the compiler will attempt to treat it as an infix method if
it can, potentially taking a term from the next line.
names toList
val answer = 42 // will not compile!
This may result in unexpected compile errors at best, and happily
compiled faulty code at worst. Although the syntax is used by some
DSLs, it should be considered deprecated, and avoided.

Why are there RichInt or RichX in Scala?

This is a simple question.
Why was not the method related to Int resided in Int?
Instead Scala bothers to put related methods into RichInt and rely on implicit conversion so as to have them work like methods of Int.
Why bother?
Scala doesn't exist in a vacuum. It was specifically designed to be hosted in an ecosystem / on a platform which was mostly designed for another language: the Java platform, the .NET platform, the ECMAScript platform, Cocoa, etc.
This means that in some cases compromises had to be made, in order to make Scala operate seamlessly, efficiently, and with high performance with the ecosystem, libraries and language of the host platform. That's why it has null, why it has classes (it could get by with just traits, and allow traits to have constructors), why it has packages (because they can be cleanly mapped to Java packages or .NET namespaces), why it doesn't have proper tail calls, doesn't have reified generics, etc. It's even why it has curly braces, not to make it easier to integrate with Java, but to make it easier to integrate with the brains of Java developers.
scala.Int is a fake class, it represents a native platform integer (primitive int in Java, System.Int32 in .NET, etc.) Being fake, it can't really have any methods other than the operations provided by the host environment.
The alternative would be to have all operations in the Int class and have the compiler know the difference between which methods are native and which aren't. But that's a special case, it makes more sense to concentrate efforts on making "enrich-my-library" fast in general, so that all programmers can benefit from those optimizations instead of spending time, money and resources on optimizations that only apply to twelve or so classes.
The question is why not model Int richly and then optimize, for example, that it has an unboxed representation and that some operations are provided natively?
The answer must surely be that the compiler is still not very good at these optimizations.
scala> 42.isWhole
res1: Boolean = true
scala> :javap -prv -
[snip]
9: getstatic #26 // Field scala/runtime/RichInt$.MODULE$:Lscala/runtime/RichInt$;
12: getstatic #31 // Field scala/Predef$.MODULE$:Lscala/Predef$;
15: bipush 42
17: invokevirtual #35 // Method scala/Predef$.intWrapper:(I)I
20: invokevirtual #39 // Method scala/runtime/RichInt$.isWhole$extension:(I)Z
23: putfield #17 // Field res1:Z
26: return
or under -optimize
9: getstatic #26 // Field scala/runtime/RichInt$.MODULE$:Lscala/runtime/RichInt$;
12: getstatic #31 // Field scala/Predef$.MODULE$:Lscala/Predef$;
15: astore_1
16: bipush 42
18: invokevirtual #35 // Method scala/runtime/RichInt$.isWhole$extension:(I)Z
21: putfield #17 // Field res0:Z
24: return