Skip to content

Instantly share code, notes, and snippets.

@gregnwosu
Last active August 29, 2015 14:07
Show Gist options
  • Save gregnwosu/bec39c586859aaaffa21 to your computer and use it in GitHub Desktop.
Save gregnwosu/bec39c586859aaaffa21 to your computer and use it in GitHub Desktop.

Scala problems

(descending in severity, IMO)

ControlThrowable

Scala exposes runtime implementation details to users! See the pitfalls around catching Throwable: http://www.tzavellas.com/techblog/2010/09/20/catching-throwable-in-scala/

Increasing the visibility of private methods is not binary-compatible

https://issues.scala-lang.org/browse/SI-8899

Scala Collections: Why not?

http://www.youtube.com/watch?v=uiJycy6dFSQ

e.g.

scala> Set(1) == Set(1L)
res0: Boolean = true
 
scala> TreeSet(1) == TreeSet(1L)
res1: Boolean = false // what?!

Type signatures are hard to read, and the simplified type signatures are misleading

https://issues.scala-lang.org/browse/SI-8876

Constructor implicit fail

Suppose I have this case class:

scala> case class C(i: Int, implicit val s: String)
defined class C

scala> C(1,"")
res0: C = C(1,)

Now I decide I want 'i' to be implicit...

scala> case class C(implicit i: Int, val s: String)
defined class C

scala> C(1,"")
<console>:10: error: too many arguments for method apply: ()(implicit i: Int, implicit s: String)C in object C
              C(1,"")

C(1, "") no longer compiles! Instead, the caller has to change:

scala> C()(1,"")
res2: C = C(1,)

Breaking callers is very unfortunate...

Normal anonymous function syntax can not destructure

Arguments in anonymous functions can not be destructured. Instead, you have to use a different syntax:

List((1,"a"),(2,"b"),(3,"c")).map(i => i+1) // works
List((1,"a"),(2,"b"),(3,"c")).map((i,a) => i) // fails to compile!
List((1,"a"),(2,"b"),(3,"c")).map { case (i,a) => i } // what I have to do instead

Haskell does this well. Java does not support destructing at all.

Type inference failure for primitive types

val s : Option[String] = Some("foo")

s getOrElse "Chocolate"
s getOrElse null // has type String (yay)

val b : Option[Boolean] = Some(true)
b getOrElse false
b getOrElse null // has type Any (nooo, I wanted Boolean)

Deviates from JVM standards

See https://code.google.com/p/guava-libraries/issues/detail?id=1095 , which leads to hard-to-diagnose issues.

Not distinguishing between call-site being able to use implicit resolution, and the implementation wanting to use implicit.

I want a constructor argument to be implicitly available in my instance, but not for the caller to be able to construct using implicitly available instance. Scala does not distinguish between these needs, and instead implicitness is propogated whenever it is passed in constructors.

Difficulties calling Java from Scala

https://issues.scala-lang.org/browse/SI-4389

Semantics of what an identifier means is case sensitive

val a = 1
val A = 1
val (b,c) = (2,3)
val (B,C) = (2,3) // does not compile

This is because you can have uppercase variables, but can not destructure to upper case variable (since it s treated as an extractor)

sbt/maven have different default conflict resolution strategies

mvn chooses version closest to root. sbt chooses latest version. This could cause bugs.

This is not a Scala language issue, but is a Scala ecosystem issue. When choosing a language, you are which is likely what you are really interested in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment