
Scala: Where it came from, Where it's going - youroub
http://www.slideshare.net/Odersky/scala-days-san-francisco-45917092
======
eklavya
Let me assure you, Scala is the nicest and most productive language I have
ever used. Don't just assume that the naysayers are right, try it yourself
(and please be fair and give it time) and you WILL love it.

I have seen people who were average Java programmers who were afraid (right to
their bones) pick it up even if out of coercion rather than willingness :P and
start to like it.

I don't understand why people suggest Java, Scala is better in every
imaginable way. Also there maybe more than one ways to do things, but I don't
get why that is a problem. Code comes from within a person like art and it's
bound to be different. Don't the large projects always have different style? I
don't see how sane code albeit written in different styles would become
unmaintainable/unreadable.

~~~
pron
The problem with Scala isn't productivity for a single developer or a small
team, or a matter of how much _you_ like it, but how productive it is in large
teams. There are big problems of separate teams in the same company writing
Scala code that the other teams can't understand, and arguments over style
taking over most of the code reviews.

~~~
6t6t6
And that cannot be solved with style guides and some kind of linting, like in
Javascript?

~~~
pron
That's not the kind of style I was referring to, but choosing among the many
ways of doing things in Scala.

------
azinman2
Funny to see people defending the complexity of the language in these
comments. So very HN.

My perspective of dev'ing in scala since 2009 (and I love scala):

"Scala isn't that complicated, just takes some time to learn."

Scala is complicated. Like really potentially super complicated, and the
compiler error messages can be hyper-cryptic. It was written by academics
(versus "developers") and it shows.

New developers will end up asking someone else a basic language question about
every 10 minutes, mostly because they don't even know what to google for.

I've been using it for years and I still have to lookup prepending versus
appending to lists because I can't remember if it's x :+= y or x +:= y, let
alone ::: versus :: versus ++ or ++=.  Really? Why not #!:@## while we're at
it?

It's crazy that in these slides he says "I wanted a hipster language" \-- most
languages use [] for arrays so I used (). WHY!!!!? Just to be different? No
actual real advantage? That's a terrible reason and a great way to make it
hard for new people to adopt your language.

It doesn't help that there are 50 ways to do the same thing and the language
is totally agnostic as to what you should do. It's almost like being an alien,
coming to Earth, and trying to learn to have sex with humans from someone who
is bi-sexual and into every fetish there is.

\---

It would be really great if they could canonicalize the language in the way
that python has, and once having done so further simplify their syntax so mere
mortals can use it effectively. Programming is hard enough without the
language being difficult, too.

~~~
eklavya
> It's crazy that in these slides he says "I wanted a hipster language" \--
> most languages use [] for arrays so I used (). WHY!!!!? Just to be
> different? No actual real advantage? That's a terrible reason and a great
> way to make it hard for new people to adopt your language.

func<Future<List<Option<String>>>> vs func[Future[List[Option[String]]]]

Which one is easier on your eyes?

~~~
trhway
>>func<Future<List<Option<String>>>> vs func[Future[List[Option[String]]]]

>Which one is easier on your eyes?

i don't get the joke here. Or are you seriously implying that one is in
someway better than the other? (i'm curious as i've been in the industry for
more than two decades, so my eyes just filter that crap automatically anyway)

~~~
jghn
Granted I'm biased as I'm primarily a scala dev these days but I've always
preferred the square brackets over the angle brackets. At least for me it is
actually more readable.

~~~
seanmcdirmid
Angle brackets aren't even very readable, couple that with the fact that they
are also OPERARTORS and you are looking at some major complexity in your
parser to distinguish between bracket usage and operator usage (possible, but
requires looking ahead, worse syntax errors).

~~~
frowaway001
Or just terrible syntax choices like in Java or Rust.

------
steven2012
I'm in the midst of learning Scala, and I assure you I'm motivated to learn
it.

However, at first pass, it appears to include all the worst aspects of Perl,
Python, etc. The one thing I hate is when a language has multiple ways to do
things, and you have to memorize them because it's not obvious. This is why I
despise Perl with all my heart.

For example, the whole "class.function(x)" being equivalent to "class function
x" annoys the hell out of me. Having _ as a overloaded magic symbol is another
perlism that also annoys me. It either means the implied array member in a
function OR it is used to tell the compile that you're passing in a function
to a variable. I hate this. Why bother using the same magic symbol? There are
a ton of other things about Scala like this that I hate because it's non-
obvious and things you just have to memorize.

That said, I'm still motivated to learn it and understand Scala, but I'm
worried I'm wasting my time.

~~~
hibikir
Being able to use dots and parenthesis or not has a very good reason for
being: It makes the concept of operators disappear. In a custom class, a + b
is the same as a.+(b), instead of doing it the Java way, where blessed Java
libraries can do things that are impossible for my own extensions. The C++ way
of supporting such a thing relies on very specific sequences of what can be an
operator, and what cannot, making things actually harder.

At the cost of making writing in-language DSL easier, like the one in
ScalaTest, the language lets people do really ugly things, if they don't like
other people reading their code. It's a tradeoff. I like to be able to have an
assertion that goes " myVal should contain("A")", and that be valid ScalaTest
code, with very good error handling, but I see how others can disagree.

Undescore is overloaded in a few more ways that you are listing too, as a wild
card in case statements and type definitions. My favorite is how we can turn a
sequence into a vararg by using the Punched-In-The-Face operator, :_ _. That
nonsense really means that we are providing a type annotation (:), and the
actual type to use should be whatever it is(_), but as a vararg (_ ). If you
know the exact type, you could go : Int _, but really, :__ works the same way.

Now, as you go through Scala, the darkest realization is not that it has too
many features, but that it's possible reach a point where you think it doesn't
have enough. I have spent most of the week bemoaning the fact that shapeless'
HLists are not anywhere near as easy to use as I'd like because the type
system needs even more power.

~~~
sagichmal

        > I like to be able to have an assertion that 
        > goes "myVal should contain("A")", and that 
        > be valid ScalaTest code, with very good error 
        > handling, but I see how others can disagree.
    

This is so _clearly_ a false economy! What you gain there in expressiveness
you lose tenfold in ambiguity — and not just in that line, but in the
latticework of exceptions you now have to keep suspended in your mind as you
read every other line of code. It just doesn't make sense to me that you'd
prefer things that way.

------
zak_mc_kracken
I don't know where Scala is going but recently, LinkedIn announced that they
were moving away from Scala and focusing on Java 8 instead.

[http://www.quora.com/Why-is-LinkedIn-getting-rid-of-
Scala](http://www.quora.com/Why-is-LinkedIn-getting-rid-of-Scala)

~~~
weego
I started off learning Scala in a 2 man band startup for 3 or so years and
moving to a company with 20+ full time Scala developers was a huge eye opener.
All the things that hooked me about Scala like taking advantage of its
relatively un-opinionated structure to be quite expressive with how you build
things turned out to be major pain points when you scale out into teams who
rotate developers on frequent basis.

I think I'm paraphrasing something I read about Twitter when I say that
everyone who uses Scala ends up taking a subset of the language they are happy
with, and that ends up being the case at a team level and intra-person level
too (starting at the new place ended up with some very frosty pair programming
sessions).

Add to that the necessity to cross train every developer who joins because
recruitment is hard enough without specifying experience in a relatively
obscure language and you have a constant cycle of painful recruitment, on-
boarding and maintenance.

~~~
evgen
Wow, you could s/Scala/Perl/g in there and it would have described the entire
Perl5 era...

~~~
azmenthe
Or C++ at any point in it's history. I guess it's the burden of being multi-
paradigm.

Edit: Looks like zak_mc_kracken beat me to it. Which I think just makes the
point even more obvious

------
lmm
As a huge Scala fan, some of this fills me with apprehension.

Existentials should always be a last resort, so it's ok if their syntax is a
bit cumbersome; I find the forSome style a lot less confusing in its
implications (e.g. "why can't I add a String to a List[_ <: String]" is a
common newcomer question) and it avoids confusion with higher-kinded types. So
if anything I'd rather drop the List[_] syntax, and use List[T] forSome {type
T} exclusively. (Eliminating existentials entirely would be nice, but they're
needed for Java interop).

The dotty approach of replacing type parameters with type members fills me
with fear. Type parameters are simple and reliable; type members are confusing
and the compiler often needs more help to get them right. I can appreciate the
desire to not have two features that overlap, but this is removing the feature
that works well in favour of the feature that doesn't.

Monads for effects work really well, and the community is just starting to get
a library stack together that makes them easy - look at e.g. http4s for where
the grassroots innovation is. They're simple to reason about because they're
just ordinary types following the ordinary rules, and we have a lot of library
support for making them easy to work with. By contrast implicits are still the
most confusing and error-prone part of the language - look at all the trouble
people have with Future and ExecutionContext. The example given in the
slideshow looks like a perfect use case for scalaz Kleisli. Rather than
another specialized language feature, the truly scalalike solution would be to
make it easier for "function literals" to have user-defined types - perhaps k{
body } to have body be promoted to a Kleisli, a la s"" interpolators.

Scala gets a lot right, and I don't think I'd ever be tempted away to Haskell
- strictness and impurity are simply too useful. Some parts can't be changed -
subtying is here to stay (and needed for interop), and much as I wish tuples
could be replaced with HLists, they probably can't. That by itself is enough
to leave room for a successor to eat Scala's lunch. But for now it's a
brilliant language, fun and safe and commercially viable; I really do love the
language, and a few of these things (union types) could make it even better.
But too many of these ideas feel like missteps.

~~~
acjohnson55
I'm not expert in any of this stuff, but reading that slide, I was kind of
getting the impression that existential types and higher-kinded types are
being unified, in the grand scheme of Dotty exploiting theoretical
equivalences of previously separated concepts. Same with the type
parameter/member thing. I think the idea is that syntax will support both
options, as seen with the analogous introduction of the value parameter syntax
for traits, but the underlying implementation will be abstract members. This
seems like it will make writing type level code or interop code much simpler,
because there's only one underlying implementation to worry about. But re-
reading your comment, I think you agree with that benefit. Do you know why
abstract members were chosen as the underlying implementation? Are they more
general?

I agree that native HList functionality within tuples and case classes would
be really huge for practical programming. It's a huge pain to abstractly
define transformations over families of classes. It's awesome that Shapeless
works, but more native support within the language could maybe help remove
some of the challenge of actually using Shapeless.

~~~
lmm
> I think the idea is that syntax will support both options, as seen with the
> analogous introduction of the value parameter syntax for traits, but the
> underlying implementation will be abstract members.

Right; my problem here is that type inference handles type parameters fine and
often doesn't handle type members without an explicit type. If the
implementation is always type members that means we're always in the
unpleasant case.

> Do you know why abstract members were chosen as the underlying
> implementation? Are they more general?

Yeah they are - there are some things you can't express as type parameters
that you can express as type members. But there's value in making the simple
case simple.

~~~
acjohnson55
Ah gotcha. Well, can't the type inference just work the same as it does now,
if you happen to use type parameters? And possibly, couldn't type inference
that works in these cases be extended to type members? I would hope that this
would be a side benefit of pushing towards more formal and unified
underpinnings of surface features.

~~~
lmm
> Well, can't the type inference just work the same as it does now, if you
> happen to use type parameters?

I think it can only work with type parameters because they're constrained in
what they can do. If type parameters compile down to type members, presumably
there is no "marker" that says that that type member obeys those constraints -
if there is then it wouldn't really be unification of type members and type
parameters.

------
virtualwhys
Scala's clearly doomed...if the comments here hold water that is. Got a
chuckle over a claim in this thread that OCaml and Haskell compile times are
"lightning fast" compared to Scala -- wow, maybe OCaml, but Haskell, I mean,
seriously, even Haskellers will raise their eyebrows with that claim...

~~~
floatboth
ghci is very fast. If you're TDDing, don't run `cabal test` all the time, use
ghci.

~~~
platz
or use something like "guard" from ruby to invoke tests on save.

------
s_kilk
It's good to hear the core team say they want to focus on simplifying the
language. I've always felt scalas reputation as a hyper-complex language was
not deserved, but it sure isn't a simple language either.

~~~
acjohnson55
I think it gets the reputation because even though it has a relatively limited
number of constructs, they're all almost always in play. And they're almost
all so basic that you'll actually encounter them on a regular basis, and often
in novel use cases. So there's a certain combinatorial complexity that doesn't
exist in languages that actually have more syntactic forms.

------
Fiahil
I used OCaml before switching to Scala professionally, and I must say I prefer
Scala's type system. It makes almost no space for errors/mistakes when you do
things conventionally, like putting types on public members.

The idea of cleaning up the syntax a bit (XML, procedure, etc..) is great, but
I'm not sure to understand what's "A better treatment of effects" (slide 44)?
What's intended?

~~~
frowaway001
Currently, Scala is an impure language.

There is some research going on how Scala can start checking and enforcing
purity. Having an IO type constructor with the usual monadic convenience
operations is one possibility, but people are actively looking into other
approaches.

~~~
Fiahil
Thank you, I wasn't sure about enforcing purity, but now its clear :)

------
lisa_henderson
Scala has always been multi-paradigm -- that can be a strength or a weakness.
Martin Odersky seems brilliant, and I've enjoyed watching some of the talks
he's given, but he also seems to define words in a way that goes against the
way I use those same words. For instance, he seems to conflate "module" and
"object" to the point that any language with "modules" is also an object-
oriented language, which is odd, since that would make Haskell and Erland
object-oriented. I'm thinking of what he wrote here:

"Objects done well provide a lightweight module system (in the sense of ML).
The requirement for a good module system is something that's often overlooked
when all you do is a simple application, but its lack becomes painfully
apparent for large systems and systems that are maintained over time. You can
go the SML route and provide a module system and a functional core language.
But then there's the pressure that you want to generalize your modules to be
more flexible, which means you want them to become recursive and first-class.
If you do that, you end up with a de-facto object system in addition to your
core language of algebraic data types and functions. Scala's approach of
unifying modules and objects is more parsimonious: The same constructs define
the core language and the module language. So Scala is simpler, in the sense
that fewer concepts are needed to describe the total feature set."

Others have already commented on this, and I have nothing more to add, but I
do find myself doubtful about whether the "Scala is simpler" is justified.
Scala has always been multi-paradigm, so I don't think of it as simple -- and,
again, that can be a strength or a weakness. I'm reflecting on what was
written here: [http://scala-programming-
language.1934581.n4.nabble.com/OOP-...](http://scala-programming-
language.1934581.n4.nabble.com/OOP-is-an-expensive-disaster-which-must-end-
td4636898.html)

~~~
tel
Modules as Odersky refers to them here (modules "in the sense of ML") do not
exist in Erlang or Haskell at all. They are a unique typing discipline.

In MLs, in large part to ensure that HM-style type inference remains
"complete", the module type language is stratified from the value type
language. This feels a bit repetitive, causes slow expansion of flexibility
and power in the module language, and makes it difficult to refer to modules
dynamically.

For some, these are all good things. In this point of view, modules are
"large" in a way that makes them difficult to reason about and so the
restrictive language they're manipulated with is vital for making them
reasonable.

For others, you might as well just unify the "large" module language and the
"small" value language. If you do this carefully you might not even lose
"complete" HM inference [0].

This is the path that Scala takes though it unabashedly tosses out HM
inference for the a highly incomplete (e.g. "local") subtype/supertype logic.

Now there's a bit of an assertion that floats around that Scala's objects are
essentially equal in power to what ML's modules would be if they were first
class. I'm not sure if anyone could quite make this formal prior to the core
calculus clean-up that is going through with dotty. Perhaps after that point
the unique features of Scala will be emphasized... or we'll truly determine
that Scala is just a unique approach to ML modules which has a different type
inference engine.

[0] [http://www.mpi-sws.org/~rossberg/1ml/](http://www.mpi-
sws.org/~rossberg/1ml/)

~~~
tomp
I'm not sure you can emulate objects with modules. In particular, there is no
"self" type with modules... or am I missing something?

~~~
jamii
No, ML modules are usually early bound which prevents open recursion eg

    
    
        module First = struct
          let rec even x = 
            if (x >= 0) then (
              print_endline "even!"; 
              odd (x-1)
            ) else
              ()
          and odd x = 
            if (x >= 0) then (
              print_endline "odd!"; 
              even (x-1)
            ) else
              ()
    
        module Second = struct
          include First
          let odd x = 
            if (x >= 0) then (
              print_endline "weird!"; 
              even (x-1)
            ) else
              ()
        end
    
        Second.odd(3)
        (* weird!
         * even!
         * odd!
         * even! *)
    

In ocaml you can use classes for open recursion but that is implemented using
dynamic dispatch. For static dispatch you would have to hack something
together using a record that is passed itself.

~~~
tomp
That's more of an issue with implementation than with typing. I mean more
like, in an OO language it is possible to declare an interface with a method
that returns the _final subtype_ (i.e. the object's _this_ type), which isn't
even know yet at the point the interface is defined.

~~~
jamii
Ah, I see what you are getting at.

They seem related to me though. Open recursion requires calling the method
from the final subtype rather than the current type - `even` would have to
call `this#odd` instead of `odd`. The core problem in both cases is not being
able to refer to the final subtype in any way.

Hmmm, even if modules could refer to this final subtype you would probably
have to choose between doing it via dynamic dispatch or sacrificing separate
compilation, since the parent module doesn't know what method to dispatch to
at the time of compilation.

------
BonoboBoner
Is the compiler faster these days?

~~~
chrisloy
Compilation speeds are largely dependent on the type of code you're writing.
At London's Scala Exchange last year, Odersky claimed he can get 10k
lines/second (10x slower than javac, but still not bad) out of scalac by
writing simple imperative code, but libraries that make heavy use of the type
system and implicit scope can be as slow as 1 line/minute.

I consider it fair to expect the compiler to be slower when it's doing more
heavy lifting, but it would definitely be nice to see the exponential blow-up
on the tail curbed in future.

edit: To clarify, the numbers above were what Odersky claimed; I haven't
verified them. The 1 line/minute was claimed of trying to build Shapeless -
I've never seen anything approaching that in the wild.

~~~
pseudonom-
> 1 line/minute

I get that that's an upper limit, but that's still pretty shocking. Is there
an overarching reason for this type of performance? Examples of this style of
code?

~~~
psuter
Code with many implicit parameters and higher-kinded types is hard to compile,
as the compiler needs to solve essentially a Prolog-ish unification problem.
Scalaz is a popular library written largely in this style (e.g. [1]). (FWIW
I've never seen 1 line/minute.)

[1]
[https://github.com/scalaz/scalaz/blob/series/7.2.x/core/src/...](https://github.com/scalaz/scalaz/blob/series/7.2.x/core/src/main/scala/scalaz/Foldable.scala)

~~~
zak_mc_kracken
OCaml and Haskell offer very similar functionalities and their compilation
times are lightning fast.

The main reason why Scala is slow is because the compiler is poorly written.
Take a look at the articles from Paul Phillips, one of the Typesafe cofounders
who left the company in frustration, he's probably the person who knows scalac
the best and he says the code base is basically hopeless.

Note that 1/3rd of Martin's presentation is about Dotty, and that's basically
where he spends most of his time these days, he hardly contributes to Scala
any more [1].

[1]
[https://twitter.com/odersky/status/574665768484339713](https://twitter.com/odersky/status/574665768484339713)

~~~
yummyfajitas
I can't speak about OCaml, but Haskell doesn't have subtypes. That's where a
lot of the complexity of Scala comes from as well as being a source of
annoying bugs:

    
    
        def f(x: Int) = if (x % 2 == 0) { x } else { None }
    

(This compiles, but the type of `f` is not `f: Int => Option[Int]`.)

[edit: the bug is not in the scala compiler, the bug is in my code - I almost
certainly did not want `f` to have type `Int => Any`. My phrasing, now edited,
was misleading. ]

~~~
zak_mc_kracken
This is correct given Scala's limitation: the only common supertype between
Int and Option is Any.

A language that supports union types (e.g. Ceylon) will type this expression
as Int|Option[Int], which is as specific as you can get.

~~~
axiomabsolute
I believe Ceylon will actually further refine Int | Option[Int] to simply
Option[Int].

Option[Int] is simply an alias to the type Int | Null, so Int | Option[Int]
would become Int | Int | Null after replacement, which simplifies to Int |
Null since Int | Int is equivalent to just Int.

------
eranation
Scala is a great language, I think it's far ahead of the curve compared to
anything else out there (swift, rust, Java 8, Kotlin, Ceylon) in terms of
being a useful functional / OO language with static typing.

One issue I have with it. I don't think it's complex, but I think people are
not spending the right time learning it. People learn the subset of features
they like and stay with it, and because there are so many ways to skin a cat
with it, everyone have their own style. It could have benefit from the concept
that other languages have of "there is always one best way to do things". I
mean, on one hand I can write 20 lines of Java in 10 lines of Scala or less
(and enjoy it 100X more) but I can do it in 1000X different ways.

We use scala on a company wide basis and even though everyone is very
expressive, well, everyone is VERY expressive.

I think that if a company enforces strict scala style rules, best practices
and sticks to it (using automatic style / structure rules that throw compile
errors / warnings and need special care to turn off) than Scala can be a big
asset to a company.

I'm sure there could have been a better solution to someone who needs a
statically typed, OO/FP hybrid language that runs on the JVM. But currently
Kotlin / Ceylon are not there for my taste. And the others, are either not JVM
languages or not OO, or not statically typed.

There is a group of very passionate people in EPFL and TypeSafe and the scala
community that don't follow Martin like a heard. there are at least 2 well
known forks of Scala compiler, one large fork of scala collections (by one of
Scala's greatest committers and also later greatest critique). Criticism is
accepted and no one follows blindly around the founder's opinions (although I
think he is doing a good job so far navigating it)

I mean, Scala is perhaps over-featured, perhaps can be a little complex if you
use it to write libraries (until you spend some time actually learning it),
perhaps it gives you too much strength, but even if it's experimental,
academic, theoretical, then it's an experimental / academic / theoretical
super fun language that I can actually use at work! how crazy is that? I think
Scala is beautiful, a pure joy to use, and I'm so lucky I can use it instead
of Java 8 or any other language in the world. Until Kotlin / Ceylon is mature
enough, Scala is the answer to anyone targeting the JVM and want a modern
language. Clojure is cool and hip, but I find it much less productive
personally, and much more complex, sorry, maybe I'm not smart enough (and, as
I said, I prefer static typing)

If you are a Java developer and never tried it, don't believe the lies, Scala
will grow on you. and unless you are a constant naysayer / devil's advocate,
you'll never go back.

~~~
frowaway001
> One issue I have with it. I don't think it's complex, but I think people are
> not spending the right time learning it. People learn the subset of features
> they like and stay with it, and because there are so many ways to skin a cat
> with it, everyone have their own style. It could have benefit from the
> concept that other languages have of "there is always one best way to do
> things".

I think that's the dark side of having both the OO side and the FP side
working well.

I'm not sure if I want something like OCaml, where everyone tells you to just
ignore the OO part of the language.

\---

I think the talk mentioned all the right things, and shows that the people in
charge listen and address issues raised by the community.

Also, just look at the productivity. Which other language can claim that
people work on a redesigned compiler, a new IR, a shared bytecode backend, and
a rewritten macro engine at the same time, in addition to developing and
evolving the current language, compiler and library?

