Lessons learned from lessons taught
I taught the infamous /: to a room of mostly Scala newbs, because I am mean like that. Or because I wish someone had forced me to learn such things earlier instead of dithering for years in an intellectual purgatory somewhere between good Java and good Scala programming. I think in the next session we’ll do Either.
>:)
For all the kvetching over methods named with non-alphabetic characters, in-fix operator notation, and right-to-left evaluation when the name ends with a colon, humans understand expressions using them just fine if they try. Or probably that is just my confirmation bias at work, but in any case the humans did not stone me.
(Also: There were no stones available.)
But here’s something that’s really difficult, you guys. The explicit type required below is basically impossible to explain / justify to beginners:
val l = 1 :: 2 :: 3 :: Nil
( (Nil: List[Int]) /: l ) { (a, e) => e :: a }
In fact, I’m pretty sure no one in the audience learned why that type annotation is needed and most would not be able to produce that expression when required to by the compiler. Which is unfortunate. I wanted people to be able to get the examples, 100%.
Sure, you can declare z with its type in another statement and maybe that’s easier to follow. But really, I wanted to be able to talk about folding without getting into type annotations at all.
Now what I was going to type here is that we should have single-parameter-list version of fold-left in the standard library so that the type inferencer could do its job better. But like any good coder I decided to check that assumption first, and guess what!?
scala> def foldLeft[A,B](t: Traversable[A], z: B, f: ((B, A) => B)) =
(z /: t)(f)
foldLeft: [A,B](t: Traversable[A],z: B,f: (B, A) => B)B
scala> foldLeft(l, Nil, (a, e) => e :: a)
<console>:9: error: missing parameter type
foldLeft(l, Nil, (a, e) => e :: a)
^
...
Boo. Guess what else?
scala> foldLeft(l, (Nil: List[Int]), (a, e) => e :: a)
<console>:9: error: missing parameter type
...
Holy crap! The inferencing here is even worse than before! We have no choice but to supply types for the function’s parameters:
scala> foldLeft(l, Nil, (a: List[Int], e: Int) => e :: a)
res24: List[Int] = List(3, 2, 1)
Oh WELL, never mind that idea. So it is probably better to start with type annotations when teaching Scala.
They’re just noise, except when they’re not.
