Hacker News new | past | comments | ask | show | jobs | submit login
Choosing Scala (software-carpentry.org)
102 points by mynegation on Nov 28, 2013 | hide | past | favorite | 63 comments

I don't come from a CS background, but I have been programming professionally many years and recently got started with Scala. I had tried Go before and I like Go. I also really like Scala.

Scala requires much more work to learn than Go. I don't think I ever ventured out much from the offical Go documentation, the spec and effective Go and the library documentation to learn Go. With Scala I've already bought 3 books, and have bookmarked nearly 100 sites. I frequently have very many tabs opened with various scaladocs, examples and stackoverflow questions open.

My favorite thing in Scala is Akka. I quite like Akka and I like the functional programming that's possible with Scala. The build tools, like sbt require getting used to but I'm able to pretty much get along just fine without an IDE. I do have intellij open but I hardly look at it. I do all coding in vim and testing with sbt.

About 14 days in and I can connect to TCP and parse JSON ok. That's where I'm at. There have been some pretty frustrating moments, mostly dealing with 3rd party libraries (like scalaz, not documented much) and sbt, but once overcome it feels rewarding.

My other favorite things in scala: it has a REPL, s"String $interpolation" and pattern matching.

Having worked with Scala for the past almost two years, I can tell you this: you're missing out by not using IntelliJ. It is a huge timesaver, not just from the code completion or the inspections, but also by being able to fire up FSC outside of IntelliJ and have your code recompile very, very quickly when you make changes. The one thing that IntelliJ doesn't do very well yet is work with sbt. It works, sure, but the maven support in IntelliJ is that much further along, so I generally still use maven for in-IDE dependencies, and then write up an sbt file when I publish my work.

> being able to fire up FSC outside of IntelliJ and have your code recompile very, very quickly when you make changes

I guess that you can achieve the same benefits with an always-open SBT console.

I usually do

  ~ test
So SBT will recompile and launch test after every :w in VIM

I use sbt for the moment. I may figure out how to get sbt to autocompile with changes. Intellij, while a very good and powerful IDE, can't really replace vim for a vim user because vim users learn vim esoterics by infusing the commands into muscle memory.

IntelliJ IDEA 13 will have a real SBT integration.

Did you know Java before? I can understand not being able to use Scalaz (heck, after three years of scala there are parts of Scalaz I wouldn't go to yet), or read other people's scala code, but my experience is that you can start writing scala to do useful things in two minutes, because you can write java (or C#) and it will work.

(Advice for understanding scalaz: look at the type signatures. Try and implement a function with that type signature yourself. In fact, the first few times I find it's best to write the thing without using scalaz myself, then notice that part of it has a type signature that matches a method in scalaz, and then replace that with the scalaz method.)

I knew a little Java, mostly from working with Android. I didn't feel like I was able to do anything within minutes. The very first thing I tried to do though was parse JSON and getting a JSON library working with sbt took about 2 days working part time.

Oh, it was the build system rather than the language or library? I wouldn't've used SBT (still don't). maven handles scala fine.

Scala requires much more work to learn than Go.

Although I like Haskell and FP, this is one of the reasons that I have been very hesitant using Scala in my previous or current position, although both were Java/JVM-heavy. Using Scala has the implication that some of my colleagues have to learn it as well, and learning FP and Scala well can be a multi-month or multi-year project.

With a language such as Kotlin, one can scrap much of the Java boilerplate, while most of it is very easy to pick up for a Java programmer in a few days or weeks.

That said, Typesafe are doing great work! I use and love Akka and it works great in Java as well (if you don't need to compose futures to much :^)).

> With Scala I've already bought 3 books, and have bookmarked nearly 100 sites.

I've also written a blog post about learning resources. Maybe it helps you: https://www.bionicspirit.com/blog/2013/05/13/getting-started...

As a word of warning, don't use Scalaz while in the learning process. It's a pretty cool library, but I've been developing with Scala for the past 2 years already and personally I've never felt the need for Scalaz.

Akka is great, the standard library is great, Play is great. You can also use any Java library you want and wrapping Java libraries in Scala-ish interfaces is great for learning ;-)

> Scala requires much more work to learn than Go.

This is true. Go is more familiar because it has a less complicated (and unfinished) type system and because it doesn't contain too many unfamiliar concepts to developers that are used to mainstream languages.

For example in Scala you end up seeing a lot of flatMaps() being used on monads, you also see type-classes or persistent/immutable data-structures, or the CanBuildFrom pattern which looks intimidating at first, but it's actually rather nice. Scala's type system is also much more static and more expressive than that of Java, Go or C# and I'm specifically talking about generics. Scala makes it easier to write statically type-safe generic code, so of course, people end up wanting more and some of them go crazy with that.

Being a static functional programming language, the type system is intimidating at first, but as you learn about it, you'll see that it's elegant and much thought went into designing it. And most importantly, it helps you to write better code, instead of just staying in your way.

Scala also contains simplifications versus other mainstream languages. In comparison with C# or Java, in Scala there is no such thing as static methods or members. In fact, in Scala all member accesses are considered method calls. This has great implications for polymorphism. In comparison with other languages that mixed OOP and FP (e.g. F#, Ocaml), in Scala all types are modelled by means of classes or traits. While using other languages, you'll notice that OOP (sub-typing) is a pain in combination with generics because covariance/contravariance is a bitch to deal with. Java's generics are broken, because at the class level they simply don't deal with it (they preferred invariance) and then for the methods themselves you've got to use wildcards. Scala is much saner in that regard. It also has a unified access philosophy that really simplifies things and the marriage that it achieves between OOP and FP is really good. In my opinion, only Clojure's protocols are on the same level while being somewhat simpler, but that goes with the territory of a dynamic language.

Anyway, Scala's learning curve may seem intimidating, but (1) it's worth it because you learn a lot about FP with Scala (the ML style, not the LISP style, which is slightly different :)) and (2) you don't need to use advanced concepts to write working code.

Have fun,

Thanks for pointing me to your blog post, that's very useful. The points about what are great about Scala also very interesting. I really like scala, despite the hard work it takes to get going.

Coming from CS and computational math background, I used mostly C++ for production and Python for prototyping and data analysis. I wanted to learn some new language for JVM, Clojure and Scala being the main (if not the only) contenders. I may learn Clojure anyway, but what tipped the scale to learning Scala first was wonderful Coursera course in functional programming by Martin Odersky, using Scala as a language, obviously.

A very short summary of my impressions from Scala: * It is beautiful, I felt the half-forgotten beauty of functional programming once again

* Scala worksheets (quick scratch to evaluate whole code snippets with immediate feedback) are awesome. I love them even more than REPL (Then again, I love IPython notebook more than Python REPL too)

* Scala seems a bit heavy in terms of number of concepts

* Scala can be terse and very expressive, but pretty verbose if you need it to be

* Compilation of large programs is slow and eats gobs of memory

* tail-call optimize everything

Are you aware of the follow-on course?


Yes, I am following that course, thank you! Although due to crunch at work I am not doing assignments for this one.

Might want to take a look at Nimrod (http://nimrod-lang.org/)

* (Mostly) Python-ic syntax (indentation-based)

* Type inferance

* OOP (but only when you want it)

* Good expressivity

* Compiles via c (FAST, easy linking with C libs, no runtime required, prodoces standalone binaries)

* Lean core (Not a "kitchen sink" language, but has good support for FP and OOP)

I'm rather excited about Nimrod, it actually looks a bit like Scala (pascal-style declarations). Scala has a lot of appeal for (most) organizations where the JVM is very widely used. I guess I tend to look at things from the position of a software engineer rather than from a teaching perspective. I'm really hoping that Nimrod gets a lot of traction (don't want it turning into a D).

I really wanted to like Scala, I came to the language looking for a Haskell on the JVM, but then just found it sacrificing too much, mainly for Java compatibility.

The close compatibility with Java does allow an easy transition for Java developers, but it's a transition to writing what it repeatedly deemed unidiomatic Scala by the Scala community. And then I've seen the same community scoff at unenlightened Scala developers that are writing "Java++".

Half of Scala could make a really nice language, but the complexity of the full thing is not something I want to work with again.

You call it sacrificing, I call it awesomeness. Scala achieves the best marriage between OOP and FP available. If you come from Haskell, you can view that as a sacrifice, of course. But I don't, to me that's a strength.

Scala is not Haskell and Haskell is not Scala. If you use one and expect the other, you'll be disappointed.

As a software engineer I find Scala to be a very powerful tool, but one which takes some time to learn. I could see it being a useful teaching tool if they stay away from obscure corners of the language. I'm glad that they didn't go with Java, but I'd only go with Scala if the students are a sharp bunch. Python would also have been a suitable choice.

> "I'm glad that they didn't go with Java"

That School (Aalto University) has used Java as a first year language for quite some time. Then they switched to Python (I think), and then to Scala. Before Java, it was Scheme. Before Scheme, I don't know.

My university switched from Java to Scheme (Racket) for their first year language.

I'm not sure why they're trying to scare the poor first years away.

I think Scheme is a good second year language, which is really when The Fear should set in among the uncommitted.

My alma mater recently switched to Scala for its intro courses, my undergrad thesis mentor really pushed for it and has written an intro textbook using Scala. He's also the reason I used Scala for my senior thesis, which led to me suggesting it at the startup I work for (first hire) and Scala becoming the basis of our backend.

I think the OP really nails the reasons Scala makes sense as an intro language. Students can start with simple concepts and gradually see how these lead to the complicated stuff.

If anyone wants to get a taste of Scala, and don't want to install anything, I created http://scalatutorials.com/tour, (no sign up, no installation, 100% free and open source) with syntax coloring and lightning fast execution of code (thanks to scalakata.com, and Scala's presentation compiler) If it looks familiar, I was a "bit" inspired by the "Tour of Go"

I really want to understand what the fuss is about with Scala so I fired up a REPL and found a tutorial and went to work. Then I can across this:

    scala> print("5" + 5)
And I stopped there (for now). At least my C++ compiler will warn about that (although it will still compile even if it doesn't print anything save for the newline):

    #include <iostream>
    using namespace std;

    int main(int argc, char *argv[]) {
        cout << "5" + 5 << endl;
        return 0;
Python gives me a TypeError. And so does Common Lisp. I was expecting the same from Scala; a language which purports to be a multi-paradigm language with static type inference and a strong functional programming bias. Not even a warning.

What's the reasoning behind this in Scala?

Scala inherits essentially all its expression syntax from Java, including the string +. This was done because a lot of other things in Scala are new, so we did not want to rock the boat too much with changes that might seem arbitrary. That said, I believe string + is probably the most criticized feature in Scala's expression syntax. People are generally moving away from it, towards String interpolation, which is available from Scala 2.10.

Thanks for joining the discussion. Just want to say I'm working through the the videos for your coursera course (https://www.coursera.org/course/progfun) and, in addition to being a great introduction to Scala, it's changing how I approach other functional languages like JavaScript and R

At most JavaScript is an imperative language with functional flavour

Try LiveScript: http://livescript.net/

JS semantics are those of a functional-oop language. It lacks a few standard functions (LiveScript has prelude-ls) and a ton of syntactic support for things. Once these are in place, you can write the code which looks and feels like Ocaml.

For example, moment.js function is `moment(dateString, formatString)`. In LiveScript I used it as:

     parseDate = (flip moment) "DD/MM/YYYY"
Now tell me that this doesn't look like functional code :)

(The only really lacking feature in JS is of course TCO, but then Clojure, so yeah, let's just trampoline everything.)

Mr. Odersky can you please take a compiler course based on Scala as well, pretty please? :P

Fair enough. Thanks for the answer. :)

  scala> "5" + 5
  res0: java.lang.String = 55
Don't use print in the REPL...

> Python gives me a TypeError. And so does Common Lisp. I was expecting the same from Scala

  scala> val i:Int = "5" + 5
  <console>:7: error: type mismatch;
  found   : java.lang.String
  required: Int
       val i:Int = "5" + 5
You can easily get a compiler error, if you enforce the type. The inheritance of Javas "I'll call .toString on anything" is definitely not something I'll defend, but it's much less of a problem than it may appear. To do anything interesting with that "fake" integer, you'll have to call a method that only accepts integers - and the compiler will throw an error then. E.g.:

  scala> math.max("5" + 5, 5)
  <console>:8: error: overloaded method value max with alternatives:
    (x: Double,y: Double)Double <and>
    (x: Float,y: Float)Float <and>
    (x: Long,y: Long)Long <and>
    (x: Int,y: Int)Int
   cannot be applied to (java.lang.String, Int)
              math.max("5" + 5, 5)

Isn't this something that type inference should catch though?

The type of "5" + 5 is inferred to be String. If you pass it to print(), which takes a String, that's not an error, and printing "55" is presumably what you meant to happen. If you tried to pass it to a method expecting an integer, you'd get an error.

It's inherited from Java, where adding something and a string will implicitly convert the something into a string.

The C++ behavior is notably worse, though: "5" + 5 in C++ is undefined behavior, and will give you a pointer to some mystery data.

The example is merely illustration and not the recommended practice for writing C++! (Can you imagine?)

I only meant to illustrate that even in C++ where types have a different meaning I will get a warning with a decent compiler.

In either case the expression in both languages garners a silly result. However Scala is happy with the result and reports nothing wrong with it (not even a warning). I was just surprised is all.

How is the result in Scala/Java silly? I'd say it's perfectly intuitive to most people that you can concatenate non-strings to strings using that syntax, via an implicit conversion of the non-string operand. You could do the same thing in C++ with operator overloading, and the unnecessary difficulty of building strings in C++ is probably one of the pet peeves of most people, and certainly something hard to explain to beginners (who will probably try "5" + 5 and be very very confused when the result is garbage instead of "55").

First off there's nothing intuitive about programming, PLs, or PLT. And certainly nothing perfect about anything related to computers at all.

    "5" + 5
Which is the sillier result: 10, "10", or "55"? All of them are equally valid based on what system of assumptions and implicit evaluation rules you decide are in effect when interpreting this expression. There are some languages that will output 10. Java/Scala will obviously choose the latter result. Neither of them are wrong.

What I think is silly is that, to my knowledge, Scala won't warn you that the result of interpreting this expression is ambiguous and their chosen implementation might not be what you had expected.

A decent C++ compiler will warn you (by default) that adding arrays of bytes to integers doesn't make sense and you are probably making a mistake somewhere. A lesser one will let you opt-in to receive warnings. A poor, silly compiler will just compile it without warning and let you figure out its strange result on your own.

This is handy for something like: scala> print("The result is " + iResult)

The problem is that you don't understand Scala operators. There are none. That + sign there is simply the name of a method in the class of the object preceding it.

So you invoked print("5".+(5))

What else would you expect. The nice thing about Scala is that you can leave out some of the extra syntax that is not needed for the compiler to decode the meaning.

Now as for why the String class has a + method to do string concatenation? I don't know but this is far from the first language that I have come across that conflates string concatentation with numeric addition. Maybe it comes from the Java libraries? In any case, it is not really a problem to most people because we follow the maxim, if it hurts, DON'T DO THAT!

    scala> 5 + "5"
    res0: String = 55

Since print() most likely expects a string, isn't the result exactly what you would expect? Why would you want a warning in this case?

You should never be able to "sum" different types, and definitely not different type families.

And I don't want a warning, I want a huge fatal end-of-the-world big red flag error message blinking on my screen until I fix it.

Because it crosses type boundaries. One would normally expect the plus method of Ints to only work on Ints, and similarly Strings for Strings.

Well, why?

I mean, I'm so used to work in Java which has the same behaviour, so I may have been totally unable to see the problem due to the familiarity of that code, maybe, but I still don't understand the problem.

First, let state the basis: the meaning of the + operator is overloaded. For numeral types, it makes the sum of the operands. For string, it concatenates them. These are two different meanings in different context.

For the numeral types, it will not protest if you sum up a float with an int (and I think most programming languages won't either). The rules of the language are quite clear: the int would be coerced to a float, then the two float be added, and a float will contain the result.

For the string operation, you could force the operands to have all the same types, but you could also practice the same kind of coercion: convert everything (yes, it works for every object of any sort) to a string, then concatenate.

OK, it may be odd mathematically, but let's see it for what it is: a very handy syntactic sugar in the form of an overloading of the meaning of +, which obey simple rules, and thus have no potential to mean something else than what the programmer meant.

The thing is, it's not just an overload; it's an overload and a typecast. Those are two separate questions, and OP is really complaining about the typecast, not the overload.

The ints vs. floats thing is kind of a red herring. In that specific case, at least you're still talking about numbers. The argument against having contagion for 5 + 5.5, and overloading for "5" + "5.5", but throwing an exception for "5" + 5.5 is that the first is a pair of numeric types, the second is a pair of strings, but the third is a pair of unrelated types. You can say white is lighter than black, and a feather is lighter than an anvil, but you can't say that white is lighter than an anvil because that's nonsense.

Incidentally, this is why, say, Python and Ruby (and I imagine Lisp) people insist upon the distinction between dynamically typed and weakly typed. If I fire up a node.js repl, I find that '50' + 5 is '505', but '50' - 5 is 45, and am reminded why JavaScript drives me nuts. In the extreme you get things like [this](http://phpmanualmasterpieces.tumblr.com/post/33198366857/lay...) and [this](https://www.destroyallsoftware.com/talks/wat). I realize that Java probably doesn't do anything near that bad, but the point is that it's a question of balancing convenience vs. error prevention, and that we're talking about a very strictly-typed language which will naturally attract people who tilt toward wanting the error detection, and even dynamic languages that swing the other way on most things often find that you don't need to make your math operators cast numbers into non-numeric types (and risk the resulting runtime errors) to have convenient string handling.

In fact, I think Ruby's string interpolation is actually a better syntatic sugar than Java's `+` cat overload. Consider that I want to print a string along the lines of "1 + 5 = 6" but with arbitrary integers. Here's how it might look in Ruby:

    puts "#{x} + #{y} = #{x+y}"
It's hard to imagine a syntax much better than this, especially for short strings, since the shape is basically identical to the string it's creating.

Python 3 is less pretty, but still reasonable:

    print("{} + {} = {}".format(x, y, x+y))
    print(x, "+", y, "=", x+y)
Meanwhile, neither Ruby nor Python makes you declare types as a rule. In fact, one of the non-backward compatible changes in Python 3 was to make it so that 1/2 returns .5, since that's how numbers work and it's probably what you meant (there are still ways to specify integer division if you want). However, in either language, if you write "5" + 5, they will raise a ValueError because that doesn't actually mean anything, is likely to be a bug, and is always easily rewritten in a concise but less ambiguous way. Speaking of which:

> have no potential to mean something else than what the programmer meant

is just false. There is a very obvious way for it to mean something other than what the programmer wanted: When the programmer forgot to cast a string to a number and tried to add it to a number. This is particularly a risk in dynamic languages or those using type inference (it's harder to pull off in languages where you have to explicitly declare all your variable types, which may make it a non-issue in Java speficially).

Some things to note:

I think you're mixing casts and conversions. At least in the parlance that I'm used to, you can only cast a number to a String or a String to a number in a memory-unsafe language (and it's rarely what you want and a bit dangerous). When you do this, the system will take your word that the data is actually a String and interpret those literal bits in memory as one. In a memory-safe language, this cast would, of course, likely raise an exception. In Scala, you can cast any object to any type with that object's asInstanceOf method.

In Scala (and many other languages), you can convert numbers to Strings and back. In fact, any object can be converted to a String via that object's toString method (which every object has as a quirk inherited from Java). Strings can also be converted to numbers via toX methods (e.g. toInt, toFloat, etc.). Of course, these conversions will raise exceptions if the content of the String does not match the format of the numeric type you are converting to.

This all matters because it is how the + method on String works: it doesn't (unsafely) cast its argument to a String. Rather, it (safely) converts it via its toString method. You may dislike the idea this method exists (I certainly do, and wish it could be deprecated now that Scala has String interpolation), but it is just a method that happens to be defined on the standard library's String type and not a major defeat of the type system.

> it's an overload and a typecast.

No, in Scala there is no typecast in that example. Everything is an object in Scala and the + method in String class accepts an object as parameter.

There is some auto-boxing happening under the hoods but that is not type-casting.

You start with an integer and end up with a string. The intermediate steps required to get from one to the other aren't particularly relevant to the point I was making.

The string concatenation API for Java IS terrible, but see modersky's post for the reasoning.

Just don't mistake a bad API for some kind of belief that Scala in general idly converts between types. The weakest point is APIs that use methods defined in java.lang.Object (e.g. toString and equals); they can universally use these methods without restricting the type.

Note that if you define a type as a knowledge of what actions can be performed on an object, then no type safety has been lost; toString() is universally available, though it may not do exactly what you want.

The issue isn't what `print` does. It's what `"5"+5` does. Even Ruby and Python throw a ValueError there.

Java compatibility. Slightly unfortunate, but less of a problem than it would be in python or lisp thanks to static typing - if you tried to pass "5" + 5 to a method that expected an int you'd get an error.

I am hoping reasoning is in a non-print application the type of the captured value will be compile time checked elsewhere. But if the language is willing to cast both ways between int and string then there is no safety (no idea if it does do that). Also I do agree with your points (explicit and implied) I don't see "hey free parsing" as a big enough advantage to infect the language with these sort of implicit conversions.

Even better:

  scala> println("5" + 5 + 5)

    scala> val pi = "pie!"
    pi: String = pie!

    scala> println(f"Care for some $pi%f?")
    <console>:9: error: type mismatch;
     found   : String
     required: Double
                  println(f"Care for some $pi%f?")

    scala> val pi = Math.PI
    pi: Double = 3.141592653589793

    scala> println(f"Care for some $pi%f?")
    Care for some 3.141593?

- http://docs.scala-lang.org/overviews/core/string-interpolati...

- read: https://github.com/adriaanm/talks/blob/master/scala-2.10/sli...

- watch: http://www.youtube.com/watch?v=tcQgNEFAVjI

FYI, this works in Java too. System.out.println("5" + 5);

All very good reasons to use Scala for teaching. I think you will also find that those students who really get it will sink there teeth in deep and not hit the bottom of the language any time soon. Thats good for those kids in the class who are comming into the university with programming experience. I know when I was doing my introductory programming classes I spent more time trying to figure out neat things I could do with C++ and Java then actually working on class work.

C# and F# would also be decent choices former being further in and the latter farther from abstract C-like comfort zone.

I see more and more F# on my twitter feed, it seems a very very nice language, terse, expressive and pragmatic.

psedit: I can't resist one of my favorite f# article http://blogs.msdn.com/b/ashleyf/archive/2012/01/26/hp-35-mic...

also, arrayForth chip emulator : http://blogs.msdn.com/b/ashleyf/archive/2013/09/21/chuck-moo...

I really want universities here to pick up Scala as well. You can teach all aspects of modern programming paradigms using it, while retaining real world applicability and the wonderful JVM and it's ecosystem.

I use typesafe stack and it's really, really good.

I use Scala in my job and, though I never formally studied CS, I would be concerned at using it for an introductory course at university.

Scala is fundamentally a pragmatic language - it is about compromise between functional purity and JVM/Java-style (OOP-based) mutation. As such, it's hard to really identify the distinctive features of either because Scala is so liberal in what it allows.

I wonder whether students would be better off learning something like Haskell along with (e.g.) Python or Java. And of course a Lisp of some kind(!).

Before you think about using scala watch this:


Paul could do a similar talk for basically every mainstream language. Better not learn anything!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact