Why do people choose 'Go' over Scala? The latter is a 'better' choice (in my opinion) for web applications and add in the play framework, you've got an ultra-fast, scalable web app. running in minutes. I do admit that Scala has a steeper learning curve, but my guess is that it's worth it.
Can anyone explain WHY Scala seems to be ignored by most of the programming community, especially here on HN, where everyone seems to be in favor of either Node.js or Go... ? Is there anyone who can provide some constructive negative feedback regarding Scala (apart from the learning curve) over GO?
Because it requires an entire JVM of baggage, is terribly complicated and doesn't really give any benefits over anything else.
Its like a Swiss army knife with a million blunt obscure tools rather than 5 useful sharp ones, or a crazy girlfriend who has three violent ex husbands who keep coming round to your house and lives with a crackhead.
Go is a trip to your Volvo dealer - uneventful but you get what you want at the end of the day and get where you want to go and when you're done, you're done.
It's false to say that Scala "doesn't really give any benefits over anything else". For a start Scala programs tend to be 1/3 of the size of comparable Java programs, with all the concomitant advantages that brings.
Do you write rants like this for every article on HN which is not about Scala? As far as I can tell, different programmers like different languages for different reasons.
I don't write webapps, but if I did, I would probably choose Clojure or Haskell or Python. You should learn to understand that by doing so, I am not insulting you or your language of choice.
Go and its tooling have a strong "straightforward" aesthetic that appeals to some people. Languages that go after power and ecosystem are in a more crowded battle for mindshare.
> Go and its tooling have a strong "straightforward" aesthetic that appeals to some people.
Yeah, specifically I see it as part of the "worse is better" school of design, of which I am a great fan. A sort of 'cat -v' aesthetic. I find that working with a language, or on products, that have embraced that mentality is just so much... calmer. It puts me at ease, for lack of better terminology.
Gopher here. I'll try my best as to why I chose Go over Scala; this isn't meant to be "why I think Go is better than Scala", it's "how Go kept me interested from zero to gopher, while Scala failed to attract my attention".
Scala didn't keep me curious for long enough to get good at it. I took a look at some examples, flipped through a textbook, and just came to the conclusion that there were way too many features and it appeared to be too clever for me to care. Things like impressive one-liners don't impress me; they do the opposite. That it's built on the JVM doesn't particularly appeal to me because I don't have any existing JVM-dependent projects. Examples like this: http://www.scala-lang.org/node/225
/** Turn command line arguments to uppercase */
object Main {
def main(args: Array[String]) {
val res = for (a <- args) yield a.toUpperCase
println("Arguments: " + res.toString)
}
}
the toUpperCase method being called without parens is bothersome to me, since it makes it ambiguous what is and is not a function call. The for loop being an expression is strange to me; it's a construct that appears to add no value to the programer, at a significant cost of clarity. It must make me seem very stupid to argue against looping constructs as simple expressions, but I think this type of notation is unnecessarily terse. Go doesn't have this type of thing, because the language is designed more for clarity than for terseness. I don't think that this is elegant:
for (a <- args) yield a.toUpperCase
I think it's far too clever. Beyond the method call, another thing that appears to be hidden here is the creation of the target list to which the uppercase letters are being stored. How many memory allocations are there in this statement? What if the body of that loop is conditional and we don't know how much space we need in advance? Yes, it's nice to look at, and I can see how it might be exciting to understand that for the first time, but... everything that it adds seems to be completely unimportant, but the operations that much be happening have been hidden from view. Great, we've saved a bit of typing, but in the process, we've lost a lot of understanding about how our program behaves.
Then there are other simple things. I really enjoy that curly brackets are mandatory on looping constructs in Go; I noticed that Scala has the feature that you can leave them off and it only includes the next statement. I find that feature profoundly annoying and prefer that it does not exist. I really like the way the tooling enforces formatting. I really like the way that Go is militant. When I write Go, I feel like I'm at work assembling an information processing machine; I don't feel like I'm writing poetry. I don't want to feel like I'm writing poetry. I'm happy to be making information machines, because that's the honest truth of the craft. The poetry lies in what those machines do; the art is in the output. To me, writing a boring program whose code is very clever is like writing a boring poem in beautiful calligraphy and arguing that the beauty of the calligraphy makes the poem better.
So that's why I went with Go, and not Scala. Of course, there are things I wish we had; specifically operator overloading and something akin to generics, the former we almost certainly will never get, while the latter remains an open question. A part of me misses having properties or Python's decorators, but... these are features that I've found can easily create maintenance problems; features that have caused trouble for me in the past.
Go, of course, has its warts (some would argue that the language made entirely of warts), but while learning the language I always got the feeling that the things that were annoying were good for me; that the warts were like being told to eat your vegetables. After a year and a half of programming Go regularly, I've found that to be largely true. My old code is much easier for me to go back to than the equivalent in other languages, and I've found my Go projects to be very easy to maintain, overall.
Go's code is the right level of terseness for me. It's far, far shorter than equivalent Java code and it's very clear. To me, elegance is clarity. To others, elegance is terseness. It's all a matter of opinion. I think you'd be hard-pressed to find someone that chose Go over Scala because of the merits of what can be built with one tool over the other; I reckon they're quite comparable in this regard.
"I don't want to feel like I'm writing poetry. I'm happy to be making information machines, because that's the honest truth of the craft. The poetry lies in what those machines do; the art is in the output. To me, writing a boring program whose code is very clever is like writing a boring poem in beautiful calligraphy and arguing that the beauty of the calligraphy makes the poem better."
Speaking as someone with a bachelor in fine arts, this rings very true for me. In Dutch, when an idea isn't working out, we have a saying: "het komt niet uit de verf," which literally translates as "it doesn't leave the paint."
With the exception of certain modern and contemporary art pieces, a painting is about what is being depicted, not about the fucking paint. The paint matters of course, but it shouldn't take the spotlight (again, ignoring self-referential topics like paintings about the experience of paint).
For loops being expressions is a source of power and uniformity in languages like Scala. It really makes your life easier in many situations. It's an unusual way of looking at loops when you come from a background in imperative programming, but once you realise that imperative programming is not the only way to compute, your life as a programmer becomes easier!
Maybe, at some point, if you have spare time, I recommend that you give a modern language like Scala, Haskell or ML/Ocaml/F# that don't distinguish statements from expressions a second chance.
I have not written my first Go (or Scala) program yet, but I have written some F# code and loved the language (and the fact that everything is an expression too). It does have som complex features, and special syntax appears very often, but after reading just a bit of documentation, I can easily understand the core concepts and syntax.
On the other hand, Scala gives me a completely different feeling: when reading the docs and samples, I often ask myself:
How can I mentally parse this?
It's nice that I can abbreviate some common constructs (when writing), but when reading code, how can I tell which concepts are being used? How do I look up these operators when they could come from anywhere (global, first operand, second operand, implicit conversion, etc.)
How do I know when parentheses, dots, curly braces, are mandatory or optional? Could the compiler misunderstand me in complex situations? Where does this construct really end if so many things are optional? At least F# uses indentation, so I know the compiler will warn me if I wrote something that is not quite right according to the precedence rules.
There are too many implicit things going on, how do I know which meaning of _ (underscore) is meant here?
I'd say this is largely a non-problem. If you already know F#, then Scala is a much simpler, more consistent language.
In a way, Scala seems to be a refined, better designed version of F#.
For instance, F# has support for functional and object-oriented programming, but most people I spoke to recommend just ignoring the object parts. That's certainly my impression, too. Compared to Scala, F# didn't manage to combine FP and OOP into a single, coherent approach. You have more or less ML's type system with the object stuff bolted on.
Another example would be that F# has tons of features where a single one could suffice. Consider the Unit of Measurement stuff, the various forms of (computation) expressions and type providers. Scala can do all of that and a lot more with "just" macros.
> It's nice that I can abbreviate some common constructs
Not sure what you mean with that.
> How do I look up these operators when they could come from anywhere (global, first operand, second operand, implicit conversion, etc.)
Not really. There are no operators, everything is a method invocation. The method is either defined on the type of the left, or added by an conversion from that type. That's it.
> How do I know when parentheses, dots, curly braces, are mandatory or optional?
Method calls with one argument can leave out dot and parentheses. If a method has a side effect, you define and call it with parentheses, otherwise you leave them out.
> There are too many implicit things going on, how do I know which meaning of _ (underscore) is meant here?
People love to make up scary examples, but I have never seen any actual misuse of implicits in real code. The meaning of the underscore doesn't change, it is always the same: "There exists something, but I don't care to give it a name."
> If you already know F#, then Scala is a much simpler
Well, F# does seem to have a lot of "bolted-on" features, but Scala always gives the impression that things "come out of nowhere", e.g. a simple underscore turns the whole expression into a lambda! It looks neat, but I will need some practice to get used to things like this. But, as I said, this is just a superficial analysis, some thing we can only learn after some practicing.
> Not sure what you mean with that.
Braces, parenthesis, dots, semicolons, and IIRC you can use the arrow => without anything on its left side.
> The method is either defined on the type of the left, or added by an conversion from that type. That's it.
Unless it ends with a colon, right?
> Method calls with one argument can leave out dot and parentheses
That's somewhat simpler than I expected. I thought it was something Perl-like or Ruby-like (where obj.method + 1 is different from obj.method +1). There should be some way to get a reference to a method without calling it, that I still haven't learnt.
> If a method has a side effect, you define and call it with parentheses, otherwise you leave them out
Not sure I understand this. Is this the preferred coding style or something enforced by the compiler?
> I hope that helps a bit!
Yes, it helped! Thanks!
Go doesn't have the ternary operator, and I thank the Go gods for that every day :)
Go is good because it's hard to write clever code in it. Go encourages simple code. Clever code is almost always bad. It's hard to understand and easy to screw up. For example, at work we had a bug in production for 5 years that short circuited our authorization code because of an incorrectly written ternary statement. If the author had written a simple if statement, the error would have been blindingly obvious. It should have been caught by tests, but due to how the tests were written, that particular path never got called.
Interesting answer. Those 2 bits are great, had to highlight them...
The poetry lies in what those machines do; the art is in the output. To me, writing a boring program whose code is very clever is like writing a boring poem in beautiful calligraphy and arguing that the beauty of the calligraphy makes the poem better.
To me, elegance is clarity. To others, elegance is terseness.
Good for you, I don't see anything interesting, you own your choice. Just another one choosing a programming language by its syntax. Good for you.
I code in Scala, Python and Ruby, because they bring different things. If I wanted to write purely elegant code I'd do it in OCaml for that matter. When I do simple things or Machine learning things I use python because it's an interesting and beautiful language with a lot of awesome library. When I need performance, strong type system with functional features, and high level concurrency beyond co routines, and parallelism I'll use Scala. Because the jvm is great at those, and Scala suits those needs very well.
So .. Good for you if Go is your language of choice.
Can anyone explain WHY Scala seems to be ignored by most of the programming community, especially here on HN, where everyone seems to be in favor of either Node.js or Go... ? Is there anyone who can provide some constructive negative feedback regarding Scala (apart from the learning curve) over GO?