Another Scala rant on HN
groups.google.com
groups.google.com
Given the headline, the cause for that thread, I expected a heated debate, laying blame everywhere. Instead I found a reasonable (if a bit defensive - if Martin is the creator of Scala I can totally understand that) poll for ways to improve Scala's flaws and image problems.
The discussion was mostly a very good read as well. I haven't written a single line of Scala in my life (I'm a fan of Clojure and F# to some degrees), but this thread looks gives me the impression the Scala community is mature and open.
Basically that thread managed to offset a number of "Scala's not working for me" reports by itself.
I'm not sure if you're saying "If the person who goes by the name of 'Martin' in the list is Martin Odersky, the creator of Scala" or "If this 'Martin' guy is the creator of Scala". In both cases, this seems to be a yes, since Martin's email address on the list begins with "ode...@".
>Seems hardly a weekend goes by these days without another Scala rant that makes the Hacker news frontpage. [...] There certainly seems to be a grand coalition of people who want to attack Scala. Since this has been going on for a while, and the points of critique are usually somewhere between unbalanced and ridiculous, I have been curious why this is. I mean you can find things that suck (by some definition of "suck") in any language, why is everybody attacking Scala? Why do you not see articles of Rubyists attacking Python or of Haskellers attacking Clojure?
He doesn't appear to even consider the possibility that he might be noticing the anti-Scala rants more readily than rants against other programming languages. Not having considered the possibility of the bias, he has no chance to try and correct for it. The wildly distorted impression he's formed leads him to language bordering on conspiracy theories ("grand coalition of people who want to attack Scala").
There just haven't been that many anti-Scala posts and discussions. Perhaps a bit more of them in the last two years, but not an avalanche by any means. Meanwhile, every language Martin's mentioned has been getting its share of attacks and (mis-)representations. Seriously, Zed Shaw's "Rails is a ghetto" rant alone has been more discussed and disputed and reblogged than _all_ of the anti-Scala posts put together, I'm sure.
Selection bias is incredibly pervasive, and you invariably succumb to it unless you consciously remember to be aware of it and try to correct for it (and then you succumb anyway, but hopefully to a lesser degree). It surprised me that Martin Odersky seemingly didn't realize that.
As for selection bias, keep in mind that many sharp people can be insecure. It's natural. But the best and brightest are able to cut through the criticisms, recognize the underlying issues, and react accordingly.
What makes matter worse is that he posted his rebuttal on the scala-debate mailing-list which was quick to support his points and reinforce him in his misguided conception that 1) there is a conspiracy against Scala and that 2) the problems brought up by naysayers can be safely ignored.
Martin simply can't admit that people criticizing his language might actually have good reasons to do so, instead, he just dismisses them and files them in the category "too lazy to learn" or "threatened by Scala".
This week-end's edition is called "Scala - 1 Star - would not program again", and it's by someone who from reading his post seems to have written Scala all of two weeks after coming form Javascript. I think the interesting bit is not so much that these posts are written, but that they are upvoted so much.
I was also very surprised to see such a low-quality blog post being voted up with such enthusiasm on HN and elsewhere.
But the fact that the article got disseminated so widely speaks volumes about the need for curation. Delegating it to users simply ensures it meets a certain minimal threshold.
Often an upvote doesn't mean I agree with the post or even its tone. Just that I want to see some further discussion.
(I don't know if this is in the spirit of HN, I appreciate it must be maddening for some people to see 'low quality' posts get upvotes).
Scala is ten years old.
Is this not an ad hominem attack? The original post writer joked about Scala syntax giving him a headache. I too felt the same way the three times I've briefly looked at Scala. I think some of the points made in that post were valid.
Even though it may not be fair, JavaScript does seem like a good language to pick for labelling someone that way, along with PHP.
Plus HN has always been a moth attracted to any flame(bait).
Clojure is mostly seen as "Lisp on the JVM", and I don't see Scala becoming more popular as anything negative for the Clojure community.
Confirmation bias.
Rust is an alternative to C and C++, but Go doesn't have a claim to that.
Now, these people are feeling slighted (however unfairly). They're not going to drop everything and pick up X. Fair enough: jumping to every shiny new technology would be madness. But chances are they won't even bother learning about X properly. Instead, they want some plausible sounding reason about why X is not all it's cracked up to be, about why they're actually smarter for not using it than vice versa, about why it's all just more hype. They want to stick it to those smug X-using bastards.
So they vote up critical articles that just happen to be written coherently, regardless of how accurate they may actually be. And so we get dross on the front page. Happily, the HN comments tend to paint a much better picture: they simultaneously debunk the original argument while exploring the actual upsides and downsides to X. With these sort of articles, the contents are worth far more than the actual blog posts.
X here is anything from Scala to NoSQL to functional programming. The recent article about what is wrong with FP and OOP is a perfect example of this, which annoyed me in particular. And yet, I think this sort of thing is virtually inevitable if functional programming is to grow and become more popular, so it's more than a worthy sacrifice.
When we, as programmers, choose tools, we make both a bet and an investment. We invest our time — both up-front in learning the tool, and during the course of a project — and bet that it'll pay off relative to using other tools. A blog post which gives a hint as to the expected value of this bet is appreciated. Hence the upvotes.
FWIW, I think Scala is a razor in the hands of a monkey, and it turns me into the monkey. I read Odersky's book 4 years ago, and it left me with a horrible taste in my mouth. I consider myself a competent programmer in Common Lisp, Clojure, Java, both C and C++ (including C++11), JavaScript, and Ruby; yet I do not trust myself with Scala.
PS: And this is just language semantics. Let's assume that Scala will eventually compile faster and solve its binary backwards compatiblity problems.
Perhaps Scala is the Napolean Dynamite [1] of programming languages.
Personally I'm also indecisive about Scala because while I'd take Scala over Java any day; I'm still hoping that something more elegant will become the next 'enterprise standard' (and I'll be programming Clojure instead whenever I get the chance.)
Scala reminds of the saying that just because the American SUV is the most elegant solution for making a family vehicle that looks masculine; it still doesn't mean they're not ugly.
Scala feels a bit like that SUV: Just because it's the most elegant solution to getting something Haskell'ish shoehorned into the JVM still doesn't make the end result elegant.
[1] http://www.nytimes.com/2008/11/23/magazine/23Netflix-t.html?...
It seems almost like a Republic vs. Democrat kind of division.
Neither side is in danger of disappearing; each views the other with derision and very few subjects ever 'cross the party line.'
Yes, I fully agree.
We jump between JVM and .NET land in our projects, whereas the myriad of wannabe be replacements are far far away from most enterprise radars.
Although many financial systems are picking it up, and a wealthy community is building around it in the .NET world, Microsoft development tools team still seems not sure how to steer it.
Meanwhile, MS has marketed F# as "financial and scientific". Remember the F# team lead is also the main force behind getting decent generics into the CLR, a concept MS corp had dismissed as "academic". So it's no surprise they aren't continuing that line of thinking.
Way off topic for the main point, but the actual problem the SUV originally solved was "how to make a mass-market passenger vehicle that counts as a 'light truck' rather than an 'auto' for various safety and other standards."
http://www.scala-lang.org/old/node/12498
I don't think it's unreasonable to respond to a very poor quality blog post bashing Scala since it received very widespread publicity. The interesting story behind the story is the extreme enthusiasm with which Scala bashing posts are upvoted on various forums. It's highly unlikely that the majority of those voting have actually used Scala.
Self-important to an extreme (We are a threat to them .. mentioned dozen+ times), often describing people who don't like Scala as either lazy or defensive. The concept that someone could be very adept at Scala, and still think it isn't a good language (and set of important libraries) is simply a non-starter for them.
That type of fundamental arrogance in a community so young is bad news -- and it appears to come right from the top.
On the upside, there was at least begrudging acknowledgement that issues actually exist.
Most posts are really about the existing problems and what can be done to improve things in Scala. In general I find this conversation very constructive and mature. I use Scala at work and see how things are gradually improving, and this conversation makes me more assured that language/community continue to move in that direction.
http://stackoverflow.com/questions/1722726/is-the-scala-2-8-...
The weird things is that despite people discussing with them and trying to correct false claims, there is almost no progress visible and pretty much the same copy-and-pasted claims will appear on the next thread.
The funny thing is, even for negative posts (bashing etc), I upvote them in HN. My intention is obviously for the technology to improve, or for people to clarify FUDs.
i for one see value in Scala, for many of the reasons outlined here, though I am experimenting and thinking it through for myself. the more interaction i have with it the more i see it as a marriage of several great worlds. One could argue that this makes for a jack-of-all-trades scenario. but let's be honest, that is what the web world seems to be demanding.
& now, to fan the flames the tiniest bit -- when I was in the RoR ecosystem it made me absolutely sick how fervently the user-base seemed to glorify and idolize it. Go to any random blog post on the internet that paints Rails negatively and you will see a stream of tl;dr comments defending it that have almost NO technical basis. just my experience anyway... and in many cases all they seemed to be defending was syntactic sugar, a tangled web of OO, and mediocre gems. But my real disappointment was that the culture of convention seemed to be a cultural of programming ignorance and non-education.
This does not mean I hate RoR, since these discussions are irrelevant. But the point is that I appreciate that Martin's views are at least rooted in programming philosophy rather than hype-mongering for or against. Scala is a student's language at the very least, whereas many other popular web languages are an uninspired grouping of OO conventions. He seems to want to educate, moreso than proselytize. Perhaps this simply makes him the devil's advocate but I see the potential for Scala to be much more than an exercise. And if some other JVM language gets a better foothold, I doubt Mr. Odersky will mentally implode. I expect more Scala ecosystem advancements far into the future.
(Please don't say + to concatenate strings, because everyone knows its terrible, its there for Java compatibility)
(That's the answer I'd give if someone asked me this question)
trait Foo {
def bar(): Int
}
and 3rd party library had final class FooBar extends java.lang.Object {
public int bar() { /** **/ }
}
you could simply define your methods to take in a: type BarAble = { def bar():Int }
But obviously if the library class is not final, you can simply do: type ThirdPartyFoo = FooBar with Foo
ThirdPartyFoo <: FooIt's a feature that you will use directly maybe once a year when adding it to a library, but I then use that library (and indirectly that feature) virtually every day. YMMV but we've found it very useful.
http://stackoverflow.com/a/267496/486561 http://stackoverflow.com/a/480362/486561
http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?t...
.NET is Windows-only, which is a significant limitation compared to the JVM. I don't think better performance on Windows -- even assuming going to CLR instead of JVM would provide that -- is a good reason for Scala to move to the CLR as the primary target.
(Still, it would be nice to have specialized generic containers for some primitive types in the JVM)
But Xamarin's porting of Java to C# to run Android on Mono without the JVM did show a rather large perf increase. I'd assume that's mostly generics eliminating boxing.
But you may be right that this might not be viable to run fast enough for JIT on a large codebase. Obviously you could tail-call enable every call that's eligible, but that probably doesn't generate optimal code. OTOH, they have tracing in the JIT for hotspot stuff, right? So if the tracing part counted how many call loops it had hit, it could decide to implement tailcalls in that path. Or perhaps it invokes analysis when the stack gets to be 75% full.
For example, consider an F#-like language on the JVM. Given the definition `let apply f x = f x`, you could imagine `apply` getting called in all sorts of contexts that don't result in unbounded recursion, so a hotspot-like system would not generate a tail call when compiling the method given the first N invocations. But then if another function is defined as `let rec loop n = if n < 1 then n else apply loop (n-1)` and invoked as `loop 10000000`, then the lack of a tail call in `apply` is fatal.
Of course it'd be better for the JVM to support this in bytecode, just like generics, stack allocation, and pointers. But it seems to me that if there was a real solid need for TCO then a JVM could implement it with tunable heuristics (most Java code doesn't need TCO, so if your code really depends on it in complex scenarios, you can always pass a -XXTcoInspectionDepth argument.)
The CLR branch, IIRC, was dropped because the CLRs reified generics -- which are better than erasure so long as your type system fits exactly what the CLR assumes -- are a very bad fit with Scala's more robust type system, which leaves you stuck with a bad interop story if you don't want to radically change Scala's type system to fit the CLR's assumptions.
- Covariance / Contravariance - Implicit Parameters - Implicit Conversions - and also mentioned here, Structural typing.
However now that i've spent time with the language, seen these in action and used them myself I see the reason why they exist and embrace them. I can see why this would be a common complaint against Scala and can be a barrier for a lot, but I think the language is worth investing time in learning, at least for me.
BTW: Kotlin has copied it and noone complains it is too complex :D
As of implicit parameters / implicit objects - ok, but what do you suggest as a replacement so that map/filter/reduce preserve types correctly? Or how do you do type-classes then?
How did delegates use variance? I've never been terribly clear on the whole delegates concept - they're like first class functions, except nominally typed and weird.
I don't have a specific answer to this question, but I do want to warn you that this is a dangerous line of reasoning. Given a complicated object like Scala or C++, you can easily have a situation where each individual element is necessary to support two or three other elements of the overall structure, yet, the overall structure can still be too complicated.
And to be clear, I'm not even saying you're wrong. Maybe there isn't a better choice. Scala's choice to be compatible with Java creates a very strange design situation. I'm just saying, this isn't a safe line of reasoning. I think it makes it very easy to become very short-sighted about your options by encouraging you to always be very locally focused.
When creating a library should my functionality exist explicitly on the types? As extension methods on an implicit? As type classes?
When should I use infix/prefix notation? When should I use . syntax vs no .? What does _ mean in this particular line of code? Is an allocation happening for this lambda or not?
Why are map/flatmap/filter magical? Why are for comprehensions part of the language for those but not for type classes?
All of these kinds of questions are really hard to answer and I've been programming Scala in production for years.
Other complaints I have are about the mess that is the collections library, the push for actors when they are generally a bad solution, an emphasis on algebraic types without providing Union types, and all the opportunity costs represented in sbt (which is finally passable but no better) and Scala IDE.
Don't get me wrong, if you are targeting the JVM & want strong typing (I do), Scala is the best language for the job, but even for someone who uses it every day and is pretty expert there are some confusing corners & no 2 developers seem to write code the same way, so there is a price to be paid for that.
1) In general, I think that going parallel should be an architectural decision. On current commodity architectures it doesn't buy people as much as they think it does, and can in many cases over complicate code. Actors hide this complexity, but don't actually remove it. People think actors give them free license to add tons of threads when they shouldn't.
2) Actor code tends to mix business logic with threading logic, precisely what we should be trying to avoid.
3) The actor model subtly conflates publisher/consumer models which tend to decompose and perform better in parallel situations.
Normally, for calculation style parallelism I prefer future/promises and for event style parallelism I prefer single writer/multiple consumer based shared memory.
The problem isn't + string-concat, it's silently casting numerics into strings.
"foo" + 6 + 6
Should be a compiler-error. "foo" + 6 + 6
>Should be a compiler-error.Why? "foo" is already a string, getting "foo66" from that makes perfect sense to me.
6 + "foo" though would be crazy.
I think that as a research language Scala is very important. It meshes features found in many different languages (OO types, algebraic types, duck-typing, macros) into one compiler, and so teaches us a lot about how these features can interoperate.
But Scala wishes to be a practical language as well. As such, I think it is an exceptionally badly-designed language (which does not, in itself, merits bashing) that masquerades, or claims to be, a well designed one, and herein lies the problem.
As Rich Hickey so eloquently puts it in one of his talks[1], a programming language is like a musical instrument. Every instrument has properties that introduce constraints. A trumpet can only play one note at a time, while a piano has very limited sustain. These constraints do not limit the artistic expression of the instrument – they assist it. An instrument with no constraints is a "choose-a-phone", and as Rich Hickey says, no one wants to play a choose-a-phone. That is not to say that a rich piece of music cannot be composed for a piano-and-trumpet ensemble. In fact, the JVM, which Scala targets, is the perfect language-ensemble tool, as it offers a harmonic interoperation of different languages of different kinds.
Scala is the ultimate choose-a-phone language, with little or no constraints. When it removed the constraints by mixing all these disparate features, it lost most of their underlying justifications. It adopted JavaScript's duck-types but lost the simplicity of the language; it adopted Haskell's algebraic types, but lost the control over side-effects; it adopted Java's OO types, but again, lost their static-type simplicity. But JavaScript uses duck typing because it can keep the language itself dead-simple and easy; Haskell uses those sometimes-hard-to-grasp algebraic types because they offer safety and carefully controlled side-effects; Java has a basic OO type system because it offers some safety while keeping the language relatively simple. Scala takes these features but drops their reasoning; in the process it lost its coherence. So the challenge of programming Scala turns from the challenge of simply expressing your artistic ideas with your chosen instrument into keeping yourself in line without those helpful constraints. It makes playing a harmonious melody difficult.
Scala masquerades as a well-designed language because it includes all of these modern, cool, features. Each of these features is well designed. But putting all of them together is the opposite of good design. The whole, in this case, is much less than the sum of its parts.
All this is not purely philosophical. Languages like Clojure and Erlang tell the programmer "this is how you should write software", and if you need to do something else, you should integrate Java or C code. Scala, on the other hand, offers little guidance. Immutable and mutable variables are just as easy to declare; the "expression problem" is sometimes solved using OO and sometimes FP. As a research language - that's great; as a practical language, it can be destructive.
It is also wasted effort. While it is certainly true that sometimes "named types" are better while other times duck-typing is more convenient, or that sometimes you want simple mutability and sometimes you don't, or that sometimes pattern matching is better than polymorphism and sometimes the other way around, in 99% of the cases, either of these approaches works well. Good, working, efficient, complex software has been written in Java, Haskell, JavaScript and Lisp. Combining all those features into one language creates big, largely unnecessary, overlaps in functionality that mostly cause confusion. This wasted effort is not just a waste; it is downright harmful, because Scala has become a very complex language. So complex, in fact, that no one but veteran Scala experts can understand how Scala's linked-list is implemented.
It is also unnecessary because, as I've said, the JVM is a multi-paradigm environment. If one paradigm is better than another for different parts of your software, you can write parts of it in Java, others in Clojure, others still in Erjang, and others in Frege. Even then you'll find that one, simple, language is perfect for 98% of your project, while another simple language is the best fit for the remaining 2%.
I think Scala's designers are stuck in their PL-research point of view. It is immediately apparent that Scala is not a language that grew from developers' needs and problems (like Clojure and Erlang), but from a PL experiment. Some years ago it might have been OK to overlook much of Scala's complexity and use it as "a better Java". Now, Scala has become ever more complex, and at the same time, better designed practical languages for the JVM have shown up. Given the wide choice, I think Scala is now a particularly bad option for a practical JVM language, especially if you're working in a large team, as every complicating language feature causes compounded damage as the number of developers on your team grows.
[1]: http://www.infoq.com/presentations/Design-Composition-Perfor...
Can you please explain more about what you think the relationship is between ADTs and monadic control of IO effects? The two are really not much related and there are languages like OCaml and F# which have ADTs but very limited use of monads - not for controlling access to IO. A monad need not be an ADT either. It really sounds like you know very little about Haskell and if you are going to criticize Scala for not getting the Haskell bits right then you really should understand it first.
data Bool = False | True
data Tree a = Leaf a | Branch (Tree a) (Tree a)The colon in python, for example, makes sense for aiding readability (and parsing) in a case-insensitive programming language like its predecessor ABC. It's completely unnecessary for parsing today. Zero-based arrays make sense in C where you have pointers and addresses.
A lot of the features of programming languages today (including the fact that they are all text based) made perfect sense in the 1960s or 1970s, when all computers were ASCII plain text-based and had very limited memory and speed. Some languages would probably be better served by an outliner than a plain text editor, for example, but that didn't exist decades ago.
Dijkstra begs to differ
I tried Clojure, and other popular JVM PL, few issues making it not practical for my team at work:
1) Many people at my team for some reason don't get along with the Polish notation (me neither, and I'm of Polish heritage) - Clojure eliminated
2) Me and my team wants a static type system - Clojure, Ruby, Python, JavaScript, Groovy and such are eliminated
3) I need a JVM language (except Java) - Haskell, Nimrod, Go eliminated
4) What am I left with? let's see - Scala, Kotlin, Ceylon, Haxe, Gosu
I chose Scala because it has, for now, the wider adoption, support, and commercial backing from TypeSafe. and most importantly, which people don't seem to consider as a crucial factor in Scala adoption- I CAN USE IT AT WORK (for some reason, Java based Enterprises seem more likely to adopt Scala than Clojure, not to mention no chance of getting approval for using JRuby, Jython or such)
If you know of another statically typed JVM language that I should consider over Scala, I would ditch it without blinking. But for now, it's the best developer happiness language out there, I have no clue why it's so popular to bash it. perhaps because it's becoming Enterprise friendly, and people hate anything enterprise these days... In any case, it's good for me, I don't mind having a language with more features, I can always choose not to use them. Perhaps the core of all problems is conventions / style guides as Martin suggested, and "how Scala should be really used" projects. I'm sure you can abuse any language, especially if it has lot's of features. perhaps we need a subset of Scala, or perhaps Scala is a language for building languages?
In any case, coming from Java, I can't go back, I rather have my overly featured Scala over my verbose Java any day.
Scala 883,000
Kotlin 21,000Scala 2.12 and Kotlin 1.0 release points should roughly coincide. Scala's got a wee bit of a head start, but if Kotlin delivers on the promise to compile as fast as Java, then for sure they'll gain traction.
Speaking of build times, just got back from the ScalaExchange conference in London (suprisingly large turnout, a little over 400 attendees). Talking with one of the Typesafe team members, it appears that Jason Zaugg (works on the compiler) recently found a way to reduce build times by 20-30%...and that's just for 2.11, good times ahead ;-)
Should point out that incremental builds + sub projects pretty much completely mitigate the "scala is slow" argument, but for deployment Jason's recent enhancements will be a boon to all Scala teams, large and small.
Scala - about 10 years old
Kotlin - not yet releasedRegarding Java 8, before knowing Scala well, I thought this will kill Scala for good. But I got spoiled by Scala's FP / OO mishmash, I got used to my duck typing, pimp my library, pattern matching, statically typed Frankenscala. perhaps it's not good, but once I figured out when to use which feature, and developed my own "Scala conventions" (not saying it was easy) I feel handicapped writing with other languages. Perhaps Scala needs a book named "Scala, the good parts" and a good Scala Lint as Martin suggested.
Will take a second look at Kotlin still, these guys KNOW programming langues.
EDIT: Kotlin looks great (http://kotlin-demo.jetbrains.com/), until I got to Delegated properties... not much better than Scala's invoke dynamic and lazy vals syntax IMHO. I love the compile to JS feature in any case!
EDIT2: correction, love observable, and delegate by map
http://kotlin-demo.jetbrains.com/?folder=Delegated_propertie...
http://kotlin-demo.jetbrains.com/?folder=Delegated_propertie...
Like CoffeeScript, this language should mainly follow OOP paradigm, while allows certain kinds of FP features, such as first class functions, seq, etc. Immutability is not forced. Basically, a Scala-minus -- Scala without Haskell stuffs, and much reduced FP features.
However, I got screwed, I now LIKE my OP / FP mishmash. Perhaps the OP is right, but too late for me, I can't work with any other language now. Haskell is too pure FP, Go doesn't have pattern matching, JavaScript is not typed (perhaps a JVM TypeScript is my ideal solution? or perhaps it's Dart?) same with Ruby and Python I'm stuck with Scala. p.s. if C# was on the JVM I would consider it as well. I'm going to give Kotlin another look though...
Now, it seems to me that that turmoil is inching into the backend and JVM. A wrong selection of technology stack would cause a huge waste of time investment. That's why some of us stand up and say no to Scala, which has been aggressively marketed as Java++ for the past few years, and seems to gain some momentum. I personally consider that's a dangerous sign, as the objective of Scala (IMHO) is to replace Java as the mainstream industry language. With the complexity of Scala, can you imagine the average Java programmer starts to write libraries in Scala? That would be disastrous to the whole JVM eco system. We all know what happened to C++.
I personally would go with Clojure, which is at least philosophically coherent. I feel comfortable working in it. Even it may not become mainstream, I am OK with that. Life is short, be happy.
As much as I would love to have a Ruby background, Ruby (mostly on Rails) for me is a hobby language / framework, can't use it at work, sadly.
I actually come from 10 years of writing mostly Java and JavaScript. I (used to) like Java, but I will replace both Java and JavaScript with Scala in any of my new projects without hesitation. Including taking into account on-boarding new team members, including taking into account how complex people can get with Scala, trust me, bad developers make spaghetti from anything, Java included, and spaghetti is not the worse thing, bad buggy code is. you'll be shocked how many Java developers don't know the contract between hashCode and equals in Java. in Scala, if you use a case class (or data class in Kotlin) you get default equals and hashCode for you, so for you little DTO bean, you'll avoid having duplicates in a set (very common Java newbie bug). Also I tend to find that huge amount of Java bugs end up having the same 2-3 exceptions - and most notoriously the NullPointerException. With Scala options, it's diminished significantly.
p.s. I did some college projects with C++, and can read it but I can't really understand the comparison to Scala, really.
So I personally won't be worried about Scala replacing Java mainstream industry world.
1) it will take a lot of time for it to happen even if HN was full of ("Scala is even better than Go / Haskell / Clojure, my eyes are opened!"
2) even if it does, I am (very subjectively) about 10X more productive with it, and write / read code much more easily with it than with the same code written in Java, but this is only because me and my team constrain ourselves to avoid abusing the language. E.g. there is nothing wrong with if(option.isDefined) if you don't like pattern matching. or using dot notation and avoiding infix notation when not really needed. I also don't care about using vars, or using while loops when it's more readable, I always provide a named function to my operators, and only use implicit conversions when it really needed and helps code readability (for example to use it for actual CONVERSIONS and avoid method overloading hell and not just to pimp a library) I also avoid one liner terse code that no one can read (or debug) and the end result is 10X more happiness, productivity and fun than with boring old Java. I also use it with Spring, Java EE and Maven instead of sbt. Scala if used this way, is indeed a better Java. But it needs guidance, so perhaps it indeed needs a "the good parts" book / style guide / Linter
p.s. If you spent some time to learn Scala and tried it on a project, and still prefer using Clojure, I'll believe you. if you say you prefer Scala over Java, I will force myself to respect you and avoid being accused of an ad hominem attack :)
Thanks for the detailed reply. You're one of the HNers whose opinions I highly respect. Wish HN had the following features like Twitter.
My understanding of Scala is very superficial. So my opinion is obviously very biased at this moment. I've been immersing myself in Clojure and ClojureScript on and off for most of this year. Learning Scala will be on my todo list for the new year. Hope I will have something to share then. I may change my opinion though, should the new version of Scala rectify most of the flaws, given the fact that Rod Johnson joined TypeSafe, who tends to have the gift to simplify complexities.
And no, I don't like Java either and consider that it's reasonable that the community needs a more expressive language on JVM and leave Java as a supporting role to write underlying performance-critial JVM libraries just like C to the native libs.
p.s. I created http://scalatutorials.com/tour as an attempt to get the basics covered quickly, it's very early work in progress, but I got good feedback so far.
Also http://codebrew.io is a great place to start playing with the language without installing anything (it even has code completion, and runs in the browser, no installation needed)
Looking forward hearing your take on it after playing with it some more.
As a practicing Scala user, I think it's pretty unfounded.
You could make the same "3 unnecessary type systems" argument about Ruby with attr_ methods, duck-typing, and classes. But I've never seen that. Maybe that's because if you're a fan of Ruby, the fact that it's Strongly Typed is pretty incidental. Things have Types, but if it's not enforced in any practical way, do you care? Pretty much not. It's a dead giveaway when people misunderstand what "expressiveness" means in the context of a type-system and go on to talk about how expressive Ruby is. Next to VBScript and JavaScript it's the least expressive language I know.
Scala isn't Java++ for me. It's Ruby++.
So maybe it's a case of differing backgrounds and expectations. I don't know Haskell. I went from VBScript, to JScript, to c#, to Ruby, to a smattering of Java, to Scala.
So from my perspective this argument is as Ivory Tower as it gets (which is a bit ironic right?). It's like suggesting Ruby needs to remove attr_ methods, or Struct. It's like suggesting that all you need is eigenclasses and you shouldn't have any label following the "class" keyword. It's like suggesting Ruby must drop respond_to.
And I have to wonder: What's the point? Would it make Ruby a better language? Is it going to make Scala a better language? No. Taking away my ability to emulate c#'s using() method with Structural Typing is not a step forwards, and it's most certainly not a case of "good design".
So eliminate case-classes? Why? Limit yourself to bolting on properties, equality, hash codes, etc ad-hoc? What's the point of any of that? It's definitely a step backwards in ease-of-use.
This is the very opposite of a practical or pragmatic critique. There are problems with Scala sure. That it simplifies a lot of boiler-plate (and really enables the FP/OO bridge) with a keyword (case class) and syntax (structural typing) isn't one of them from my perspective.
I don't have a problem with Scala as a Ruby replacement. I do have a problem with it as a Java replacement.
If you are writing massive software to handle comprehensive control for an aircraft carrier, you'd better be writing it in loosely-coupled components with well-defined interfaces, or its going to be a maintainability nightmare no matter the language features.
If you are doing that, Scala's flexibility lets you, internal to each component, take the approach most suitable for the team responsible for that component addressing that components requirements.
I can see where Scala's flexibility could make a bad situation worse if you are writing an enormous piece of software but not doing it in loosely coupled components but instead doing a tightly coupled nightmare -- the OO equivalent of spaghetti code -- but, even though it might be less of a disaster, that's still going to be disaster in Java or C#, too.
Exactly! I wish more people knew both Scala and Ruby well enough to notice it
This notion of simple also confuses me. You mention Javascript, and while I agree Javascript is easy to write I would certainly not call it a simple language. There are a huge number of inconsistencies, gotchas, and just plain head scratches littered throughout. And let's not even get started on the hot mess that is prototypical inheritance in. Java is hardly simple, it's outdated and probably one of the main reasons there is a movement to other languages are because of the lack of new paradigms integrated into it's core, but that certainly doesn't make it simple. I can show you some pretty nasty Java code bases that can be just as if not more confusing then some of the worst Scala code I've seen out there.
In terms of focus, I think Martin and the community has been pretty clear about what Scala is about, an OO based functional language that focuses on practicality over theoretical purity. If it was meant to be an academic language why focus on Java interoperability so much? One of the beauties with Scala (though some might disagree) is you can basically write it to look just like Java, which is why it can have a leg up over a language like Clojure, whose syntax is so different. Why include mutable state at all? That certainly isn't a trend with academic languages, but it certainly is practical to allow when performance reasons dictate it. Why create Typesafe and have all this focus on strong native build tools and good IDE integration? I honestly don't think Martin just decided one day out of the blue that he wanted to make Scala a practical language, that's been part of the game plan from day one. The precursor to Scala, Funnel, was dropped specifically because he didn't feel it was a practical language and he started over and wrote Scala.
I think Scala has been finely tuned for it's purpose, to provide an elegant synthesis of functional and OO paradigms that allow developers not use to those ideas to slowly wade into that new world. That's the way I was introduced to it and that's the way I know many other developers have been introduced to it, with good results. Having worked at a few different companies of varying size, all with large code bases in Scala, all training new people with the language, I can say it's definitely possible to get large teams working on complex problems to adopt it and thrive. And I'm starting to see more and more adoption, both in the enterprise and at startups as well. I think plenty of people are jiving well with their new chosen instrument, it's fine if you don't like to play it, but I don't think it deserves to get knocked off as an unplayable mess as a result.
The distinction I want to draw is between types of teams. Some teams are very very organic, they let most of their developers do their own thing and they come together relatively independently. In these teams, having the language dictate approach isn't just handy, it's critical to keep the system coherent. You can instantly say during code review “yeah, that's not how it's done in Clojure”. Scala doesn't have the same level of guidance. Style is dictated by the frameworks you choose, and even then there's room for error. I use style, by the way, not as meaning “please use two spaces instead of tabs”, but rather as “parameter order in these cases should be this, method names should be structured like this, our class names usually look like this”, etc.
The other team is the team that has a clear single or group of guiding individuals who have a vision of how they want the system to work on a stylistic level, and who can explain that vision to the rest of the team. For these types of teams, where those individuals enjoy the process of coming up with the vision, Scala can be exactly what they're looking for, because they can develop the style that fits best with the system they're building. This shouldn't be confused with architecture. Architecture is important, but style is not a subset of architecture, it's an overlapping set.
A choose-a-phone is difficult for a single instrument player who is used to constraints, but for someone who likes to push the edges of constraints and come up with just the right combination of sounds for this particular piece, a choose-a-phone gives them the freedom to do that without having to pull in seven different instruments. Indeed, if we could make a choose-a-phone, I doubt every symphony composer would shirk it—I suspect some would embrace it. Not as something for research, but as something that lets you produce a different kind of musical piece. It wouldn't work for every composer or orchestra, but for those who could establish a coherent sound from the vast range of the choose-a-phone, it would be a fantastic opportunity to create something new and, from some perspectives, better.
The way I've successfully used Scala has always been about discipline. You choose the path you want to follow through the language, and you stick to it via code review. If you discover a new corner or feature of the language, you discuss its usefulness and choose to either incorporate it into your existing processes or not. Could you just say “let's use this other language for this”? Yes. But Scala lets you explore a large set of opportunities within a similar syntax, and use them where they are appropriate. If the syntax is what bothers you, or if the particular approach to a given piece of functionality is what bothers you (this has happened at times in my experience), then you can explore a different language; Scala certainly doesn't preclude you from doing that. But your first forays and prototypes can be within the context of a language everyone on your team already knows, making for a smaller incremental step. Smaller incremental steps mean faster iteration, and faster iteration means faster decisions on whether something is a good idea or not.
Scala more than many other languages doesn't dictate approach. But that doesn't mean approach doesn't matter. It means the approach ball is in your court. Pick the wrong one, and your experience will probably suck. Let that taint your view of the language if you wish, but keep in mind that there may be an approach that will be a lot nicer. For some people and some teams, that's not what they want out of a language, and that's fine. For some people and some teams, that's exactly the kind of empowerment they want, and that's fine too.
There is no difference in practicality, only in personality.
PS: I love Clojure and Erlang, too ;)
So you do get choice, but it's more of a choice between a Paris-style and a New York-style Las Vegas hotels rather than between Paris and New York. Scala is Las Vegas, only it runs on the JVM which offers cheap supersonic flights between Paris and New York.
Also, the kind of team you describe can't really be a big one. I might see it working for 15 people; maybe 20 if they're really good. But 50 and up? I don't think it's going to work.
I can count on one hand the number of times I've had to do casting in Scala over the course of writing four different web applications of various sizes in it. Fine-grained control over side effects is only a benefit if you consider it a benefit, and is IMO far from the greatest benefit you can get from a strong, flexible type system. Easy mutability has little to do with type safety—indeed, type safety makes mutability marginally safer by at least holding you to a basic promise when you make mutations. I can't deny Scala is heavier than JavaScript, I suppose, for some definition of heavier that I assume means “has more features”, or means something that ends up equating to same.
To argue that writing software in both Clojure and Java (or pick 2+ other languages that all run on the JVM, of course) will leave you with an objectively lower complexity:benefit ratio than using a single language is a dubious claim indeed. I don't guarantee that just using Scala will always result in a lower such ratio, but you'd have to make a much better quantitative argument to convince me that you can have a lower ratio consistently by using different languages instead.
To deal in increasingly-divergent analogies one more time: if your work is in Las Vegas, you may not care that there are cheap supersonic flights to other cities. They will never compare to being able to do all of your work in Las Vegas, even if it means switching hotels depending on your needs on a given day.
I've worked on projects that used C++, Ada and FORTRAN; on projects that used Java, C, and some homegrown DSL; on projects that used C++ and Scheme. In all circumstances, the integration of languages proved simpler than "disciplining" the C++ programmers, and on the JVM that integration is a lot simpler than what we had to put up with back then.
Also, bear in mind that team members change, as do team leaders. That proved to be a big problem for C++ projects as the discipline changed over the lifetime of the project.
If you look at Odersky's presentation "The Trouble with Types" [1] at Strage Loop 2013, he describes Scala as a "type it to the max language" like haskell, ocaml or F#. He seems to be aware of the complexity problem and proposes a few ways to reduce some of the type complexity.
BTW, to reiterate some of what's been said in other comments, I am certainly not opposed to using Scala in "Ruby style" projects (though Clojure would be a better option for those, too, IMO); I do, however, think that it's a very bad alternative for large Java projects.
How big is the team? How many years of maintenance have you had on those projects? I remember C++ looked pretty awesome for a while. It was certainly great for one-man projects or small team. Then the problems started piling up. Thing is, C++ didn't have any good alternatives (maybe now we'll have Rust); Scala does.
That was not the point. The comparison is that Scala is to Java what C++ is to C.
Powerful and flexible but with a lot of baggage that ends up making it impractical.
Which is pure opinion/speculation.
If making analogies, a much closer analogy would be to say Scala is to Java what D or Rust is to C++.
As of lots of baggage - can you elaborate? Only null comes to my mind and it is never an issue - it was left because Scala is practical. Sure, there are some limitations imposed by the target platform like lack of TCO, lack of efficient suport for tuples/value-types, or RTTI for generics being not powerful enough, but Java-the-language has nothing to do with it. The same limitations apply to Kotlin and Ceylon.
It will be based on Scala, and similar enough that, if things work out, we could have Scala.next without a Python 2 to 3 glacial transition.
Of course, Scala 2.1.x branch is making great strides as is, and AFAIK, the DOT language is still a research project, so not likely that we'll be seeing Scala.next anytime soon.
I like your musical instrument analogy, and to steal it, I would say that Scala allows you to be the composer rather than the musician. To be an effective composer, you need to know the qualities of all the musical instruments so they can work together harmoniously. You can write a beautiful symphony, or you can create horrible noise. But the power to do so lies with the developer/composer.
That said, arming your large development team of average developers with such powers might indeed be asking for trouble. That's why Rod Johnson, in his recent Scala Days address [2], challenged the Scala community to address this problem if Scala is to be the "next Java".
[1] http://saddle.github.io/ [2] http://www.youtube.com/watch?v=DBu6zmrZ_50
As to the few constraints, keep in mind that my point is that those constraints are or at least directly lead to benefits. So few constraints mean few of the benefits. Scala mostly enjoys the "few lines of code" benefit that Ruby developers like, but not the more important benefits of a solid, well-considered, easy-to-maintain language.
From that perspective, it is very possible to right clean, maintainable, succinct, performant code in Scala with classes, case classes, pattern matching, immutable data structures and the stackable trait pattern. Scala 101 as far as I can tell is fairly obvious if you have done a lot of Java programming - you know where the pain points are and how Scala can shorten or eliminate the problem. I think something which would serve the great majority of Java developers as a better Java.
As a Scala newbie, I didn't find it hard to get there to understand how I can sunset my Java programming with Scala, and I'm having a hard time finding a reason to go back. The arguments against Scala (like yours) seem to often get lost in big ideas (being a lifelong musician myself Hickeys instrument talk was only marginally inspiring), whereas I'm looking at LOC and syntax and I really like what I see. I can do the same thing in Java, but with more effort.
I think the only benefit Java enjoys right now is better tooling. It still might be the best choice for large teams due to way it shoehorns development styles (and I actually don't mind coding it in at all, its pretty nice), but for my personal projects, I'm definitely focusing on Scala right now.
Here's a different premise: Scala combines fp and oo while keeping things simple because it is coherent -- more so than languages such as Java.
So, for instance, when you complain about Scala's algebraic data types, you completely miss the fact that Scala doesn't have them. There's no type in Scala that isn't a class.
Instead, various Scala features are combined to support ADT patterns through the OO type system, and these features are designed to work in concert to produce various desirable effects, instead of having stand alone features serving a single purpose, without coherent integration with the rest of the language.
Take Java, for example, and some things it has that Scala doesn't: static declarations, primitive types and arrays. Each of them are completely at odds with the rest of the language: they serve a single purpose, they have their own rules, and they cannot be combined. That is bad design.
Let's consider one of the features you mention that Scala actually has, and see how it fits: structural typing. Scala doesn't have structural typing because all the cool kids are doing it or some other non-sense: it serves a purpose in the language, and solves a number of problems in a coherent manner, with a single set of rules and in a way that combines together with other parts of the language.
Specifically, it generalizes Java's own duck typing, which, apparently, you never realized it was there (because Java is such an ad hoc language): anonymous classes extra methods. There's no explanation in Java's type system for why anonymous classes may have extra methods and use them. They are simply allowed for anonymous classes, and that's that.
Scala, on the other hand, introduced "type refinements". It is exactly the same thing: extra methods. However, it is not a standalone thing dissociated from the rest of the language: one can call these methods because they are part of the type refinement. And because they are part of the type refinement, it also means they can be visible from outside the anonymous class, and even specified as the type for parameters.
And that's where the "duck typing" comes in: it is simply the type of an anonymous class that extends Object whose extra methods are visible from outside the anonymous class itself. Not an extra feature, compared to Java, but an existing feature of Java that got integrated.
The pattern continues: while Scala has just classes with refinements, Java has classes and primitives and arrays. While Scala has just methods and assignment, Java has methods, static methods, operators, fields, assignment (of which multiple kinds exist!), and array index access and assignment.
It's not that Scala has many disparate features: it has a core of well designed features, and they are well designed because they allow use in many different ways.
Now, if one thinks a language should constrain its user, then Scala is not a language for that person. But, please, don't invent problems that don't exist because you expect them to be there: if you want to criticize it for anything other than not being to your taste, at least get to know it first.
I'm surprised you're pointing out bad design decisions in Java (that I agree with) and point structural type as a good Scala design decision.
Structural typing is terribly designed and avoided overall for all these reasons. For example, asInstanceOf doesn't work with structural types but works fine with traits and classes. That's bad design.
Here is an example showing how broken structural types are:
scala> type Mappable[A] = AnyRef { def map[B](f: A => B): Mappable[B] }
<console>:7: error: recursive method map needs result type
type Mappable[A] = AnyRef { def map[B](f: A => B): Mappable[B] }
I have about three other mystifying compiler errors due to the fact that structural types are very badly integrated in the language overall.> It's not that Scala has many disparate features: it has a core of well designed features, and they are well designed because they allow use in many different ways.
I think you are not being very objective in the way you see Scala. A lot of its features are terribly at odds with each other, such as mixing inheritance and type classes (which one should I use and when?), the eleven ways in which the underscore character can be used, currying and its bizarre syntax, the odd rules when you can omit parentheses and when you can't, when to use parentheses and when you should use braces, etc...
Scala has tons of disparate features that don't fit very well with each other, and it's very similar to C++ in that respect.
There are bad consequences arising from that, but it was a trade off that was made taking into account the failure of Scala's predecessor, Pizza.
Among these things there's asInstanceOf, which you should generally not be using in first place. That said, you can use asInstanceOf with structural types:
scala> object X {
| def f(a: Int, b: Int) = a + b
| }
defined object Xscala> val y: Any = X
y: Any = X$@aebbca6
scala> val z = y.asInstanceOf[Any { def f(x: Int, y: Int): Int }]
z: Any{def f(x: Int,y: Int): Int} = X$@aebbca6
scala> z.f(2, 3)
res6: Int = 5
Your example definitely doesn't show structural types being broken: it only shows that type refinements cannot be recursive. This might be limiting, but it is not broken, and it was a necessary trade off to integrate structural types into a nominal type system -- something that was thought to be impossible.
Inheritance and type classes: type class is not a Scala feature, it is a design pattern that uses other Scala features together, so there's no "clash" here, because there's no feature.
The eleven ways in which underscore can be used is not something "at odd" either -- it's just the same symbol used in eleven different contexts to mean eleven different things. It saves on reserved keywords/characters, at the cost of making the language more difficult to learn, but there's no conflict between their uses.
There's nothing bizarre about currying syntax -- you may not like how it looks, but it's perfectly functional. Maybe you like point free programming, but that is NOT a style favored by Scala, intentionally so.
The rules for omitting parenthesis are actually rather simple: you can omit parenthesis around the parameter of a single-parameter method when that parameter is enclosed in braces itself; you can also omit parenthesis around a parameter of a single-parameter method whose parameter type is a tuple.
Now, even if I had not an answer for each case you raised, you have failed to show that they don't fit well with each other. You have criticized each one on their own, in isolation, and, in fact, failed to appreciate how they actually show their strength when combined.
Some examples of that:
* Omitting parenthesis combined with by-name method parameter passing allows for DSLs that look like native language constructs; * Implicit parameters, type inference and nominal typing can be used together to produce the type class pattern; * Abstract data types and inheritance can be used together to create a module system.
...to exploit the real power and appreciate design choices takes months if not years...
It sounds like the benefits of Scala are very subtle, and I would love to read an informative overview of them and why they are hard to master.i can imagine a fair amount of negativity coming from app and system developers thinking "oh god, not yet another story about yet another hipster web dev language we don't need... yet again! when will web developers ever learn! when will i get a language /i/ want..."
i'm sure it is great for some domain, but i've yet to really play with it or find myself wanting it somewhere.
to be fair, most of my language excursions away from c and c++ are from either pure curiosity or a platform holder ramming it down my throat.
Now what I won't do is try to apply all the patterns I have learned over the time and try to force it on a LISP language and then say that it is shitty because x. I would rather take some time to learn the LISP way of doing things and be more enlightened for having done so.
Of course Scala is heavy on types. It is advertised as a feature! why the surprise? Why won't you come along with us and try to do things our way once and see if you like it?
This is the pure essence, of why people here at HN love or hate some language/technology
As a experiment, try to talk badly about javascript or anything from apple
The community here are completely biased, and its all about hypes.. any technology that require more effort and dont make the guy looks like a genius in 5 minutes of programming is not worth it in their view..
its not a problem with the language, its a problem with the community.. Its the generation of "genius: cooked in 15 minutes"
nevermind the bollocks
My point is, there is a cult.. and thats what make the rating mechanism so unfair with other technologies that are not the mainstream ones
I saw it happening with Java, now its Javascript.. and soon will(probably) be Go
yet, they are all the same paradigm of C.. some sintax sugar here, some FP there.. yet.. same paradigm.. nothing that would make you create something never seen before in other language.. just more noise and vanity
That said, he should probably not take any criticism personally. They are discussing Scala the language, not Martin the creator of that language.
I don't think this makes HN look good in any way.