I went to the Typelevel Summit / NE Scala Symposium this week. It was my first time going to a Scala conference, ever. At this point I’ve been working in Scala professionally for about ~1.5 years.
My goal in attending NE Scala was to see what Scala looks like outside of my particular corner of the universe. I write Scala at Twitter, which has a particular style; and I’ve only worked on one team at Twitter, which makes my view even narrower. Scala is notoriously “flexible” as a language, i.e. put three Scala devs in a room and you’ll have at least nine dialects. What does Scala look like when other people write it? What challenges and interesting problems do people have? What are people excited about?
It turns out that I had inadvertently picked a conference that’s known for being a little more functional-programming-theory-heavy and less about “pragmatic” Scala. One of the other attendees said to me, “I feel like I write blue-collar Scala compared to this.”
I have Strong Feelings about jargon. Jargon comes with an inherent cost. It needs to earn its place. (And it often does: jargon is necessary to discuss complex and domain-specific ideas.) But…eh. There was a lot of jargon at this conference.
Here’s some jargon that I heard at the conference that I didn’t understand:
- free monads (sometimes with a capital-F)
- monad transformers
There were also some Scala concepts that I’m familiar with but admittedly don’t use often in my own code, like implicits and certain operators like
|@|. (These are really hard to Google for, btw, which is one of my biases against them.)
And again - I want to emphasize this - I manage to be a productive software engineer in Scala without these concepts. These are not mandatory bars to entry, at least in my workplace. But I wanted to learn more about them, so here we go. (Spoiler alert, it turns out that many of them were things I was already using but didn’t know the names for. Neat.)
Shoutouts to the following people for teaching me things, sending me great links, etc:
Note: I probably get some things wrong below. Got more stuff for me to read, or thoughts? I’m @brindelle on Twitter.
Apparently monoids are just things that 1. have an identity function (aka no-op) and 2. have an append function.
This sounds so simple. OK then!
(s/o to Kelley Robinson’s talk )
I’ve always been a bit embarrassed to admit that I don’t really grok monads. The good news is that when you admit you don’t understand something, people usually send you great links / answers.
@b0rk replied to me and was like, aren’t monads just things with flatMap? Which was a bit of an ah-ha moment for me. I have plenty of experience working with things with flatMap! And that’s clearly a pattern for which I don’t currently have language. Hmmmm.
Libby Kent sent me a link to her talk, Monads Made Semi-Understandable. Best quote: “Can you explain what monads are? Are they a burrito?”
This was an even bigger ah-ha moment! Ah, yes, this is a thing I’ve worked with but only have an inferred, non-systematic understanding of.
Monads (in Scala) are things with flatMap and apply defined. In other words: monads let you compose functions for values in a context. Common monads are: Option, List, Try, Future.
flatMap lets you nest functions.
The Monad Laws, as defined by Libby’s talk: they boil down to “don’t do weird shit inside of flaTMap or apply”.
monadA.flatMap(a => apply(a)) == monadA
flatMap(f).flatMap(g) = flatMap(a => f(a).flatMap(g))
Googling this also led me to Monad laws in Scala which was useful.
The first talk at NE Scala was by @djspiewak, in which he built up something called the Free monad from scratch. This was confusing because I had never heard of free monads before and didn’t know what they were, or why they were useful or interesting or etc.
So! Today I watched Kelley Robinson’s talk, Why the free Monad isn’t free. The Free monad is apparently a pattern that lets you separate out function composition from computation/interpretation.
“Free” here means “unrestricted”, not “zero cost”.
Free monads should not lose any data during the composition (
flatMap) step. So we can’t evaluate any functions as we do this. So we store up the data (e.g. the functions) as we’re building the structure; and then we’ll evaluate it later.
It’s not something that’s “built in” to the language or anything like that; it’s a pattern for structuring how you handle stuff. You’re delaying evaluation (aka side effects). There are implementations available in Scalaz and Cats.
What’s the point? Separating composition from computation seems really great for testing, since you’re separating out side effects from the wiring / composition step.
However, it involves a lot of boilerplate, and a steep learning curve. Means building up big interpreters, too. I hear that there are also some performance issues with this in Scala?
Free from interpretation; don’t lose input data when appending.
Example: list concatenation doesn’t involve interpretation. Integer addition, on the other hand, loses information during the input step.
Express it in a loop: use the heap instead of the stack.
I actually really like this phrase, it’s cute.
The tagline calls it a “lightweight, modular, and extensible library for functional programming” which tells me …. absolutely nothing about what it is, except that it’s for functional programming. OK? Can’t I do functional programming in a bunch of languages without a library?
Wait, just kidding, the README actually has a great introduction:
Cats is a library which provides abstractions for functional programming in Scala.
The name is a playful shortening of the word category.
Scala supports both object-oriented and functional programming, and this is reflected in the hybrid approach of the standard library. Cats augments the standard library with tools that further enable functional programming such as Validated, Monad, and Traverse. A broader goal of Cats is to provide a foundation for an ecosystem of pure, typeful libraries.
Given that Day 1 of the conference was the Typelevel Summit, it makes sense that there was much discussion of Cats.
This one has a better Github tagline: “Automatic type class derivation for Cats”.
OK! Cool. I like these puns but there were fewer cat GIFs during presentations than I would have liked.
From http://spark.apache.org/: “Apache Spark™ is a fast and general engine for large-scale data processing.”
The “killer app” for Scala, apparently. Interestingly, a lot of Spark code is apparently not very functional at all. (As usual, programming for data science looks different than other kinds of programming?) There were lots of Spark users in the audience.
No side effects. That’s it??
This is a free monad thing, it means “don’t do the computation yet”.
This is what the apply method does in Scala: “lift” a value into a ~monadic context~. I guess it’s sort of like putting something into a different abstraction?
From Libby’s talk: apply lifts a value into a ~monadic context~ (aka the context of whatever you called
map “lifts” a function into the same.
Something that takes a monad and turns it into another monad?
“A type which wraps a value”. More at this blog post explaining applicative functors.
“A family of types that has implemented the map method”; there’s an identity function, and also grouping doesn’t matter.
Kelley Robinson’s talk, again: https://youtu.be/U0lK0hnbc4U?t=5m21s
Laŭ Kelley Robinson’s talk, again, “functors are endofunctors” in Scala.
“endo” = mapping from one category to itself; in Scala that means mapping from a Scala type to a SCala type.
There is a very math-y usage of this word. I still haven’t found a good concise definition for it.