Why does these lines of code freeze the Scala/SBT build? - scala

Transitioning from Play Framework 2.1 to 2.2 (Scala) I was restructuring some code and found some lines of code to totally freeze the SBT build until the process was killed due to java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: GC overhead limit exceeded. Also Eclipse (tried with Juno and Kepler but I doubt it has anything to do with this) froze and it didn't even load the workbench anymore.
So, here's the code. I would love to know what makes the compiler to freeze and not just give an error here.
def foo = Action { implicit request =>
someForm.bindFromRequest.fold(
formWithErrors => Ok,
form => Async { Future.successful(Ok) }
)
}
I solved the issue already, but I'm curious why this just freezes everything. I'm on a Mac running java (1.7.0_40).
Update: Also, I'm using Scala 2.10.2. A coworker of mine can compile this on his PC, but with deprecation warnings on Async.

There are certain expressions within Scala that when you ask the compiler to evaluate them, it will instantiate a TON of type instances trying to figure out the unified difference between two types. Most likely, the type you're returning is NOT what you expect.
I would explicitly annotate the result type:
def foo = Action { implicit request =>
someForm.bindFromRequest.fold[Result](
formWithErrors => Ok,
form => Async { Future.successful(Ok) }
)
}
This should help the type inferencer KNOW what the types are and only check to see if they match, rather than expand infinitely. Also, sounds like it may have been a scala compiler bug.

Related

Equivalent of scala.concurrent.util.Unsafe in Scala 2.12

I have created empty instance of my object and then initialise it using run time values. Implementation was based on scala.concurrent.util.Unsafe in Scala 2.11 and it worked fine.
I understand Unsafe is bad and hence has been deprecated in Scala 2.12.
If it's deprecated then what's equivalent of Unsafe in Scala 2.12?
Assuming you're running on a JVM where sun.misc.Unsafe is still available (this will limit which JVMs you can run on, but so did using scala.concurrent.util.Unsafe so no immediate loss):
val unsafeInstance = // use in place of Scala 2.11 usages of scala.concurrent.util.Unsafe.instance
classOf[sun.misc.Unsafe]
.getDeclaredFields
.filter(_.getType == classOf[sun.misc.Unsafe])
.headOption
.map { field =>
field.setAccessible(true)
field.get(null).asInstanceOf[sun.misc.Unsafe]
}
.getOrElse { throw new IllegalStateException("Can't find instance of sun.misc.Unsafe") }
Code is very slightly adapted from the Scala 2.11 source.
It's possible that this is an instance of spending so much time thinking about "could" that one didn't think about "should".

Prevent 0-ary functions from being called implicitly in Scala

I got nipped by a production bug where I passed an impure 0-ary function to a class that mistakenly expected a a bare result type.
def impureFunc(): Future[Any] = ???
case class MyService(impureDependency: Future[Any] /* should have been () => Future[Any] */)
Effectively, this made MyService immediately invoke impureFunc and cache the first result for the lifetime of the program, which led to a very subtle bug.
Normally, the type system prevents these sort of bugs, but because of the ability to call 0-ary functions without an argument list, the compiler accepted this program.
Obviously, this is a "feature" of Scala, designed to make code look cleaner, but this was a bad gotcha. Is there any way to make this a compiler warning or a linting error? In other words, disapprove the "Empty application" type of implicit method conversion?
From the comments here, it appears this behavior was deprecated with a warning in 2.12 and should become an error in 2.13. So it seems the answer is to use -deprecation -Xfatal-warnings after upgrading.

Lightbend examples syntax error

I just wonder if I have messed something up or is it just unavoidable pain of using Scala. I wanted to test out slick so I decided to run activator-play-slick-angularjs example from Lightbend. Unfortunatelly I get syntax errors while using
lazy protected val empTableQuery: TableQuery[EmployeeTable] = TableQuery[EmployeeTable]
in any possible way. In filtering examples, the type I am required by Scala plugin to use is Any e. g.
def delete(id: Int): Future[Int] = db.run { empTableQuery.filter(_.id === id).delete }
_.id part yields syntax error. I bet that I am just missing something because I can't imagine a single developer willing to work in 2017 without syntax assistance from IDE.
In case somebody met this problem in future - in this example EmployeeTable is defined with private[EmployeeTable] what makes in not visible in EmployeeRepository class. Just skip the private[EmployeeTable] part in class definition to make everything work smoothly.

Why am I getting an (inconsistent) compiler error when using a for comprehension with a result of Try[Unit]?

A common pattern I have in my code base is to define methods with Try[Unit] to indicate the method is doing something (like writing a transaction long to a SaaS REST endpoint) where there is no interesting return result and I want to capture any and emit any errors encountered to stdout. I have read on another StackOverflow thread this is entirely acceptable (also see 2nd comment on the question).
I am specifically and explicitly avoiding actually throwing and catching an exception which is an extraordinarily expensive activity on most JVM implementations. This means any answer which uses the Try() idiom won't help resolve my issue.
I have the following code (vastly simplified from my real life scenario):
def someMethod(transactionToLog: String): Try[Unit] = {
val result =
for {
_ <- callToSomeMethodReturningATryInstance
} yield Unit
result match {
case Success(_)
//Unit
case Failure(e) ->
println(s"oopsie - ${e.getMessage}")
}
result
}
Sometimes this code compiles just fine. Sometimes it doesn't. When it doesn't, it gives me the following compilation error:
Error:(row, col) type mismatch;
found : scala.util.Try[Unit.type]
required: scala.util.Try[Unit]
result
^
Sometimes the IntelliJ syntax highlighter shows the code as fine. Other times it shows an error (roughly the same as the one above). And sometimes I get the compiler error but not a highligher error. And other times it compiles fine and I get only a highlighter error. And thus far, I am having a difficult time finding a perfect "example" to capture the compiler error.
I attempted to "cure" the issue by adding .asInstanceOf[Unit] to the result of the for comprehension. That got it past the compiler. However, now I am getting a runtime exception of java.lang.ClassCastException: scala.Unit$ cannot be cast to scala.runtime.BoxedUnit. Naturally, this is infinitely worse than the original compilation error.
So, two questions:
Assuming Try[Unit] isn't valid, what is the Scala idiomatic (or even just preferred) way to specify a Try which returns no useful Success result?
Assuming Try[Unit] is valid, how do I get past the compilation error (described above)?
SIDENOTE:
I must have hit this problem a year ago and didn't remember the details. I created the solution below which I have all over my code bases. However, recently I started using Future[Unit] in a number of places. And when I first tried Try[Unit], it appeared to work. However, the number of times it is now causing both compilation and IDE highlighting issues has grown quite a bit. So, I want to make a final decision about how to proceed which is consistent with whatever exists (or is even emerging) and is Scala idiomatic.
package org.scalaolio.util
/** This package object serves to ease Scala interactions with mutating
* methods.
*/
package object Try_ {
/** Placeholder type for when a mutator method does not intend to
* return anything with a Success, but needs to be able to return a
* Failure with an unthrown Exception.
*/
sealed case class CompletedNoException private[Try_] ()
/** Placeholder instance for when a mutator method needs to indicate
* success via Success(completedNoExceptionSingleton)
*/
val completedNoExceptionSingleton = new CompletedNoException()
}
Replace yield Unit with yield ().
Unit is a type - () is a value (and the only possible value) of type Unit.
That is why for { _ <- expr } yield Unit results in a Try[Unit.type], just as yield String would result in a Try[String.type].

Scalastyle "Public method must have explicit type" in Play Framework

We've started experimenting with Scala and the Play framework at my work. Setup our auto-linting and testing framework as the first thing, and have deployed Scalastyle to handle the former.
That has been very useful, except that we are getting this specific lint error that we are finding it difficult to resolve in a good way. A simple example is this:
def helloWorld = Action {
req =>
Ok("Hello World!")
}
Though often it can be much more complex, of course (to the point where it can difficult to figure out what the type actually is).
In either case, this gives us the "Public method must have explicit type" error from Scalastyle.
Unfortunately, setting the expected explicit type here seems typically to cause a syntax error.
Any suggestions on a good solution for this? Or do we just have to turn of this check for Play projects?
Any suggestions on a good solution for this? Or do we just have to turn of this check for Play projects?
I'd suggest to either turn org.scalastyle.scalariform.PublicMethodsHaveTypeChecker rule off completely for your project or mark your controllers to be ignored by this rule (here you'll find info on how to do this).
In the end this check benefit more to people who write libraries (as it helps to be more explicit about api one provide). I found that when you're working on "real" projects check like this does nothing but adding some boilerplate and stops you from leveraging type inference.
I hope this helps. To to Settings -> Editor -> Scala -> Type Annotations. Change the value to 'Add' instead of 'Add & Check' for Public value and method. Then it IDE will not show that warning anymore.
I've found a better way for removing the "Public method must have explicit type" message, without turning it off.
When defining these methods, the body [type] and [implicit] [type] may be set; as Action[JsValue] and implicit RequestHeader for example.
Code example:
def helloWorld:Action[JsValue] = Action {
implicit req: RequestHeader =>
Ok("Hello World!")
}
or
def helloWorld:Action[AnyContent] = Action {
implicit req: RequestHeader =>
Ok("Hello World!")
}