Man that's a bad post about Scala. Scala has a lot to love and a bunch to hate within the language itself, but writer doesn't appear to have the ability to actually discuss it.
Fortunately it's feedback that the community has taken to heart. 2.11 should improve compile times, as will new incremental compilation features in SBT 0.13. IntelliJ's Scala support has gotten much better recently and the official Scala plugin for Eclipse has also made major strides. (Though I still use vim)
Odersky has taken an official stance against symbolic method names, especially in libraries, and many of the most famous offenders (Dispatch's absurd periodic table) are rightly ridiculed within the Scala community.
I don't have anything to add on implicits. They've certainly tripped me up a few times but generally it's just a matter of finding the right import, though I have been cursing Play's implicit JsValueWrapper the last few days.
That's good to know. I haven't used Dispatch since 2011 when I first started using Scala (that was a rough introduction). I'm looking forward to Play moving their WS package out of the core though—right now we've basically written a few wrappers around AHC in their style for the pure Akka parts of our stack but we'd love to standardize.
Scala doesn't have operator overloading btw. It just doesn't restrict method names very much. This is very different from how C++ treats operators as special cases.
If you give your methods bad names, it really is not the language's fault. You can probably find a way to make a bad API even if you are limited to a-zA-Z0-9 ...
If a library has an inscrutable set of method names blame the lib not the language.
I know that, and I use the term only because the author did. I agree that it's the fault of library designers not on the core language, but it is still a legitimate issue to raise.
Well the problem with Scala is at first it looks like a concise java but it's not. Truth is it's closer to Lisp with a C syntax. If you dont understand some idioms like lazy evaluation, everything is a method or pattern matching you probably should use it. I think scala rocks. The only downside is the slow compiler. But SBT , worksheets , stuff like that are just awesome to toy with stuffs in an interactive manner.
Scala is much closer in spirit to ML / OCaml / Haskell than a LISP dialect, but I do agree w/ you that Scala rocks. It's my favorite language I've picked up since O-Caml.
The only similarity that Lisp and Scala have are that they are both functional programming languages[0].
Scala is a heteroiconic language. At least until recently, Scala didn't even have macros (I think they may have added that recently).
Scala is a nice language, but saying that Scala is somehow like Lisp is doing a disservice to both languages.
[0] Even the statement that Scala is functional is itself debatable - one can make the argument that it is "just" more purely object-oriented than Java, but that's a whole separate discussion.
Why do people think Lisp is a functional programming language? If anything, traditional Lisp is the antithesis of a functional programming language. What Lisps are you referring to?
Maybe we're just defining our terms differently, but the closest Lisp comes to a functional programming language is Clojure and before that Scheme.
This is not meant to deride Lisp in any way (Clojure is my language of choice, after all) - I think all Lisps enable a fundamentally unique way to reason about programs, but that's a characteristic of Lisp and not of functional programming languages.
I think the biggest thing is that most lisps return values for most things.
(if a x y)
which is composable to
(let ((val (if a x y)))
...)
as opposed to
(let ((val nil))
(if a
(setf val x)
(setf val y))
...)
That said, not everything returns value(s), and there's nothing enforcing immutability. I'd say you can be functional in (most?) lisps if you are careful, but the language family is more geared towards general purpose programming than functional.
Unfortunately we've overloaded the term 'functional programming' a bit too much. Foundation on the lambda calculus is definitely core to most functional languages, and I see how it would be reasonable to think of that as their defining feature, but it seems that the community has instead gravitated towards 'referential transparency' as the key thing. With the former definition, Lisps are definitely functional; with the latter, most of them are definitely not. Most Lispers I know consider e.g. Common Lisp to be a multi-paradigm language, not a functional one, for this reason.
Lisp is the original functional language. Functional language traditionally meant a language that emphasised functions as values, in particular supporting higher-order functions. Hence the word "functional".
More recently, people have confused "functional" with other features of languages like Haskell (sometimes called "purely functional"), leading to some confusion about what defines functional programming.
Here's an interesting post about the more recent changes in the phrase's meaning:
No it isn't. Those tell you what types the values represent. We're talking about the actual source code itself. In lisp, the source code is itself a perfectly ordinary lisp value. That is what homoiconicity is. That is not something scala has, nor is it something scala wants to or claims to have.
This bizarre lisp fetish where everyone wants to call every language "basically lisp but..." needs to die. Scala is not basically lisp. Neither is python, or ruby, or javascript. Lisp is not just "has lambdas".
My main impression after using Scala a little bit (admittedly some time ago): it has some very cool functional features, but they are too slow when compared with the non-functional features. When working on a program for which performance matters, this means that you end up working on a Java-like subset of the language in most of the program.
Well I would argue that when you are working on something where performance matters on the JVM you end up working on a very C-like subset of your language. Java makes the translation to that subset easier than Scala, but you can certainly do the same translation from Scala.
Scala has a couple of features that make it by far the best programming language ever conceived by mankind. But it has a couple of other features that utterly ruin it with total unrecoverable brain damage.
I would really, really appreciate a Scala without all the crazy, but with all the brilliance. Or, you know, just a community that doesn't go out of its way to overuse all of that crazy.
Just drop the incomprehensible type declarations and the incomprehensible operators. Maybe add dynamic typing, even. Then you'd have a really nice language.
I keep hoping that the operator abuse is just a growing pain. The language community has been given a new toy, and they're going to chew on it.
Eventually libraries that will come along that were intended to be used by humans. Sbt will disappear. Flowers will bloom, and the lion will lay with the lamb.
Moving to a simpler type system is not the only option. If you want to avoid the incomprehensible type declarations while increasing the strength of the guarantees the language makes at compile time, you might consider OCaml.
I really disagree with this article. Type safety combined with Play's refresh-recompile trigger means it is not meaningfully less productive than PHP, and maybe moreso because compiling is usually an indication of your program's correctness, so you don't waste time tweaking-reloading-tweaking-reloading. Compiling is slow, yes, but it saves you more time than it costs you because static typing means a whole class of bugs just never happen for you.
I know that the IDE support is lacking but this doesn't really bother me since I don't use an IDE with Play apps. I always use a text editor, since I find that IDEs tend to do a bunch of things badly, whereas a text editor and a terminal each do a single thing very well. There's nothing you said about the features of an IDE that I couldn't do just as well with a well-defined find-replace (besides variable extraction - not familiar with variable extraction.)
You can be productive in any language - Java, Scala. But I find that Scala's conciseness - the fact that I can do an operation on a whole collection of case classes using pattern matching and the collection API functions that would take 30 lines using classic Java - ends up making me more productive than I have been in those other languages. Maybe it's just me.
For someone learning Play & scala in general I find the IDE to be immensely helpful in showing my type information and valid auto-completes. Rather than constantly digging through documentation I can see that, for example, some flatMap will give me a list of (Id, User) tuples, so then I can call map( case(id, user) => user) ) (or just map(_._2)) and pull out the user objects to get my list of users from my list of tuples. This lets me focus on the business logic and not spend all my brain power tracking types. I don't think I would have survived my first foray into building complicated composite ResultSet parsers in anorm without the IDE.
I'm sure that as I gain more experience and all the functions become second nature I'll be able to track it in a text editor but for now I love my IDE.
So, how do you write your unit tests? Within grails and guard (and other systems as well), I save my file and I have all the relevant unit tests running immediately. I have less than a second lapse.
At least, when I was working within play, it was painful enough to discourage me from test driving my code, especially if implicits were involved.
will only run previously failed or new tests on file save.
On one Play project we have ~160 test cases, including integration tests that spin up real Neo4j and Elasticsearch instances. Running the whole suite takes around 90 seconds. That would be far less if I did a better job separating unit and integration tests or mocking out the external dependencies.
I spend most of my time running specs2 - unit specs - from the command line. I'm sure I could have sbt trigger on save but since I save pretty much constantly I'd have the tests running all the time. I will freely admit the compile time on tests is a bit extreme but I've found that it doesn't appreciably slow me down, since I typically run the tests when I'm confident the new code will pass.
As for integration tests those run via Specs2/Selenium as well but I rarely run them from my own machine as they are continuously running on Travis CI whenever I push to our repositories.
Not sure about the state of the play framework, but the standard Scala build tool allows you to do the exact same thing as grails & guard using the ~test-quick operation.
I've tried dropping an Intellij several times while programming Scala, but have never figured out a VIM/Shell configuration that gives me what I need.
That is:
- Type safe re-factorings (why would I give up on my type system to just go grepping around my code base?). To be honest I don't use variable extraction as often in my Scala code as I did in Java, but to have never used it makes me think you are severely undervaluing the whole type safe re-factoring universe.
- Automated import statements.
- Configurable code formatting.
The IDE space is improving dramatically in Scala, but I do think the Scala teams blessing of Eclipse was a mistake. They should have been writing more generic tools/hooks to empower their users in a wide variety of development setups.
But after you've waited 10 seconds (in my experience, with a single code change it is usually more like 2 - 3 seconds) what you've done has a greater likelihood of working the way you intended, since it wouldn't have compiled at all if your intentions were less well-defined.
Perhaps, but I've already gone back to surfing the web in those 10 seconds. And scala provides pretty poor type safety compared to how bad the compile time is. I don't actually use PHP, I was just pointing out how the claim that play's workflow is just as productive is inaccurate.
> Except with PHP you hit refresh and it is done. With play you wait 10 seconds and it is done. There is a huge difference.
eh? With incremental builds you should be seeing far more 1 second recompilations than 10 second recompilations.
If you're getting 10 second recompiles, the following help:
1) sub projects, it's an absolute must for non-trivial apps
2) use a 3rd party build system (say, GruntJS) for assets
Also, be sure to ;clean;compile prior to starting an incremental build with ~run (and of course, do this from a play> prompt and not bash, you want a warm JVM)
Good point, there's a lot to learn in Scala land as well as many ways to shoot oneself in the foot, cold JVM is a good place to start, ouch, glacial development ;-)
I was testing with a trivial app, so 1 doesn't apply. There were no assets, so 2 doesn't apply. Ghc is notoriously slow at compiling, and it managed to recompile/reload the equivalence haskell test app in the time it takes to alt+tab and hit refresh.
Got a link to this trivial Play app that takes forever to compile (and the equivalent lightning fast Haskell app), or shall we just take you on your word?
Yes, I keep every test app I've ever written on hand just in case an infamous language_X troll demands proof anytime I mention that I saw the sky once and it looked blue.
Exactly this. Developers need to think holistically. Sure, maybe you can F5 your way to basic functionality, and that might make it seem like you're saving time in the short-term, but you also need to account for the hours and hours of painful bug hunting you'll occasionally (but inevitably) incur when that one sneaky null reference or fence-post error makes it into prod.
Interesting post, a little random, ultimately it's really hard to 'prove' something like this in a single article. Studies maybe, but there'll always be someone saying something contrary.
I can only really offer my experience, which is architecting and building out a 25kloc app and team to go along with. Mostly, because we avoided the 'clever' scala stuff as much as possible, things went well. Maven instead of sbt. Jetty instead of play. The only scala DSL we used was squeryl.
If I was doing it again, I'd probably rethink the use of scala. As helpful as it was, it was also a pain in places. Having to rewrite all our for loops was not cool. Case classes saves on boilerplate, but frankly you only write that stuff once, so it didnt really save us on a lot. Intellij elides most of the junky boilerplate (import statements, generating setters/getters, etc) in Java, so ...
Now a days with the advent of Java8, we have access to lambdas, function pointers/interfaces, and the functional stream system, I am interested to see how far one can get in just pure java. Java is the new scala it seems.
you've never had to only have 1 class per file. You can only have 1 public class per file however. You can also nest classes in other classes for quick little data types you need locally.
So the notion that every single last tiny class has it's own file hasn't ever been true (even if thats the coding style in a lot of code).
No, in fact you frequently have more when you start using case classes. Plus you frequently have the companion object that goes with your class that acts as a singleton.
I understand the limitations of Scala with regard to class/trait/objects etc. What I'm asking is if it is still an issue in Java 8? I'm shocked every time I drop back into java land that people haven't revolted against this terrible requirement.
Because it adds friction between separating implementation and interface. That is one of those things I want to be as seamless as possible. Is it a big deal in the case of 1 interface and 1 class? No not really. But in the case of thousands of them it becomes an issue.
It's actually one of the biggest things I notice when I come back to java land.
This works until he wants something other than a single loop in his function's body, yes. It's probably best to use the @tailrec annotation as the second answer does, since if you're writing Scala you're probably targeting a godawful runtime that can't actually do TCO, and you'd be in a pile of trouble if you messed up and your compiler ended up not doing it either.
If you need loops within loops, nothing stops you to have tailrec functions called within other tailrec functions. Any loop can be rewritten as a tailrec function and I prefer tailrec functions because it's easier to me to guard against invariants changing or to reason about branches or exit conditions. Plus with algebraic data-types, the compiler can warn you that you missed a branch. Etc... Also, the compiler does optimize plain for-loops on ranges. You can even have a macro that rewrites your nice looking for loop into a while expression.
On mutually recursive tail calls, yes, the runtime doesn't have support. Because it misses support for TCO, you're ready to call the JVM "godawful"? Might consider that .NET's tailrec support was basically a guideline that didn't work on 64bits .NET up until .NET 4.0 [1] and it's still not optimized, having a rather significant performance hit versus normal function calls.
For the JVM, a prototype for optimized tail recursive calls is in the works and given the attention that invokeDynamic received lately, I have no doubt it will be implemented for JDK 9 [2], especially given that people like Guy Steele are calling for it [3].
Either way, it's not so bad to implement mutually tail recursive calls by means of trampolines in Scala, especially given that you have an expressive type system at your disposal [4].
> you'd be in a pile of trouble if you messed up and your compiler ended up not doing it either
TCO is considered an optimization, not a guarantee, so if you want it to do a TCO by contract, then an annotation makes sense, no?
> On mutually recursive tail calls, yes, the runtime doesn't have support. Because it misses support for TCO, you're ready to call the JVM "godawful"?
Some JVMs such as Avian support this feature, so they may not be godawful. I haven't used them much, so I don't know.
> For the JVM, a prototype for optimized tail recursive calls is in the works and given the attention that invokeDynamic received lately, I have no doubt it will be implemented for JDK 9 [2], especially given that people like Guy Steele are calling for it [3].
This is great to hear, thanks for telling me about it :)
It sounds like I will have a better time in JVM-land next time, if I ever have a reason to go back.
> TCO is considered an optimization, not a guarantee, so if you want it to do a TCO by contract, then an annotation makes sense, no?
In JVM-land, this is the case, which is why I said one should be careful to use the annotation. I don't have a problem with using the annotation. I do have a problem with TCO not being guaranteed in the language spec (like Lua), or at least supported by popular runtime+compiler combinations (like C++).
A very important point for me in Scala is that now I can consider building the company stack with it. The libraries and infrastructure are really getting better. We have Play for web applications, Spray, Scalatra and more for APIs, actors / futures / STM / Akka for concurrency, and you can easily intergrate Akka with Play and Spray, use the same patterns at different parts of your infrastructure. We have Scala.js for frontend work. Growing numbers of frameworks for Big Data. Those are maturing and being developed for industry needs, tested in production at some known companies. Don't forget it's based on solid JVM with huge amount of Java libs available.
I have confidence to advise building real businesses with Scala stack and not looking like an irresponsible guy who just wants to play with the latest and shiniest stuff hazarding a company's business. I also see how Typesafe is focusing on solving bad parts: compiling time, stability, etc.
You can also stay away from advanced / theoretical / crazy parts of Scala most of time. You don't need to use Scalaz, advanced type system features etc. There are also immature libraries, toys and proof-on-concepts, but you cannot blame Scala for your choice.
I'm curious about the fact that you're using both Play & Spray. Are you using them in the same app? It seems like there's a lot of overlap between the two and that by switching to Spray as your backend you'd just be generating static HTML with Play.
Spray (or Unfiltered at my previous project) is used for a different part of the project. It's basically used on parts where you can expect high load, lots of requests / responses and tight integration with Akka system for processing large amounts of data. Play framework was used to provide UI for our data team or end users to see statistics, do some operations and it's not bombarded by large amound of requests.
Makes sense. I'm building out on Play right now but given that my long-term goal is to have a JS view + REST endpoints I'm still not decided on whether I want to stay on the Play UI/template model or switch to something like Backbone.js + Spray.
Spray is the better option for "web API"-type projects, but doesn't have the support for making a frontend UI that Play does. I understand that going forward there is a plan to port Play to run on top of Spray.
>You can also stay away from advanced / theoretical / crazy parts of Scala most of time.
The parts that make it worth using in the first place?
>You don't need to use Scalaz, advanced type system features etc
Might as well stick with java then. You're not getting the benefits of scala vs java, but you are still paying the costs like compile times and poor tool support.
I didn't experience "poor tool support" with Intellij IDEA. Java performance profiler also worked well, command line too. Maybe I am not very exacting.
Sticking with Java you lose both the expressive Scala features and some good frameworks without Java burden.
Btw under "advanced parts" I didn't mean "everything above Java". I enjoy immutability, collections, case classes, pattern matching, first class functions, lambdas, terse syntax not considered them "advanced parts". Advanced parts are all those lenses, recursive types, type lambdas, you know.
I used IntelliJ IDEA to write Scala for 2 years. Such complex operations as renaming a variable or getting a list of uses of a trait would frequently be done wrong, so I ended up checking the IDE's work every time. The Java-to-Scala tool emitted code that would never have compiled on any version of the Scala compiler. Using the IDE's auto-import feature would frequently end up importing * from a package, which would cause the file to see the wrong definition of some class name that occurs in multiple packages, so it was important to check the IDE's work even when the only task I gave it was to import a class.
I used IntelliJ IDEA for about 1 year and I never encountered a single instance in which this IDE got a rename wrong, or a "find usages" for a type. I also never got an importing wildcard to shadow some important definition that I was using from another package and in fact it bugs me that lately I can't get IntelliJ IDEA to do wildcards imports were it can, because I don't like dozens and dozens of imports from the same package.
What it does wrong is when copy/pasting code or when moving a class/trait to another file/package, it sometimes misses the imports for the implicits that the code is using. You can't really blame it, since an imported implicit is not hard-wired in the same way an explicit reference or type usage is. Depending on your perspective, this may be a feature and not a bug :-)
Either way, IntelliJ IDEA gives awesome in-editor error highlighting and you also have Scala's compiler to double-check things for you, so you really don't have to double-check the IDE's work, except in cases where there are problems.
> The Java-to-Scala tool emitted code that would never have compiled on any version of the Scala compiler.
It's pretty hard to translate from Java to Scala and you're right that it doesn't work. On the other hand, idiomatic Java code is pretty freaking far from idiomatic Scala code and I think you should either leave that Java code as is (mixed projects are easy to configure) or you should translate it in idiomatic Scala code by hand, a task that no transpiler could do.
> What it does wrong is when copy/pasting code or when moving a class/trait to another file/package, it sometimes misses the imports for the implicits that the code is using. You can't really blame it, since an imported implicit is not hard-wired in the same way an explicit reference or type usage is. Depending on your perspective, this may be a feature and not a bug :-)
This does sound like a feature and not a bug, yes.
> It's pretty hard to translate from Java to Scala and you're right that it doesn't work. On the other hand, idiomatic Java code is pretty freaking far from idiomatic Scala code and I think you should either leave that Java code as is (mixed projects are easy to configure) or you should translate it in idiomatic Scala code by hand, a task that no transpiler could do.
I agree, but some of the team used IntelliJ's make and apparently our particular project configuration had trouble with Java in some projects, so where there wasn't much Java the solution we went with was to move it to Scala. There were other more reasonable solutions available like "Fix the config" or "Just use xsbt bro", but it wasn't my call.
Almost everything you listed as not in java is in java 8. Your distinction between "advanced" and "stuff I like" is a false one. Other people who aren't familiar with what you are familiar with will call those things "advanced". And when you learn those things you call "advanced", you will move them into the "stuff I like" category.
Java 8 doesn't have immutable collections, nor would I consider Java 8's lambdas to constitute first class functions. Java 8 doesn't have function types, just functional interfaces.
What makes Scala worth using is a good type system, pattern matching, excellent support for concurrency and powerful DSL capabilities. None of these are crazy or require you to write mind-bending code.
Scala has a poor type system, and poor support for concurrency. It's terrible DSL problem is not a selling point. Nothing he talked about was crazy or required writing mind-bending code, that is the point. IntelliJ's scala support is still, to this day, completely broken. Have you tried using it?
Do you know how to handle compiling time in a large project? I know Twitter uses Scala in prod so there must be a way. I am wondering how they handle that.
The OP jokingly names a law after himself at the end, but I move that we do name something after him. I'm going to call it Ahmdal's Condition. It goes like this:
In this lengthy [post|comment], I’ll share my thoughts and opinions on [THING IN COMPUTING, TiG hereafter] . . . Using a cavalcade of flawed data; logical fallacies; biased opinion; startling lack of citations; and basic nonsense, I will convince you that using [TiG] will make you less productive. I will finish with an underwhelming and unexciting conclusion. You have been warned.
Think of it! "I'm offering my thoughts here under Ahmdal's Condition, of course . . ." "Well, I think you're starting from Ahmdal's Condition . . ." "That works under Ahmdal's Condition, but assuming stricter conditions . . ."
Honestly, it's genius. If I had a magic meme wand, this guy would be famous by the end of the day.
Is it necessary to provide randomly controlled trial/other scientific data to talk about things you don't like in a programming language? Do you have the same standard for talking about things you do like in a programming language? My only problem with the article is that the hyperbole/sarcasm (e.g. "I've given irrefutable scientific evidence...") is not so well done.
Even first hand anecdotal evidence has its limits. It really needs to be blatant to be significant. Second hand anecdotal evidence is even worse. If the phenomenon you want to catch is subtle, you generally a good deal of reliable data. That generally means something "scientific".
My point is that people demanding scientific data for criticisms had better do the same when their favorite language gets praised. Of course, personal evidence is less strong than scientific evidence. That much should be obvious to anyone.
> My point is that people demanding scientific data for criticisms had better do the same when their favorite language gets praised.
Ah, the dreaded double standard. Easy trap. Personally, I avoid it by trying to have objective criteria. I end up with crude and imperfect measures (LOC count, number of defects…), but at least they're not too biased.
> personal evidence is less strong than scientific evidence.
Actually, this is not necessarily true about first hand personal evidence. While a host of biases are out to cloud your judgement, science can be weak for two reasons: (i) the studies may not amount to much evidence, either because the controlled experiments are also artificial, or because there may not have been much of them (it is quite expensive to do the same project multiple times with arguably similarly skilled teams), or both. (ii) What applies to the majority of people may not apply to you specifically (though you'd better have strong evidence as to why this is the case).
Now, second hand personal evidence… that's much harder, because (ii) doesn't apply, you also have to trust whoever is telling you the story, and this story hold far, far less information than what you would have gathered by living it yourself. Still, it may yet be stronger than sufficiently weak scientific evidence.
Now, a blog post by a random programmer? Okay, that one is always weaker than science.
> I’ve been developing software professionally for a whopping 3 years.
So much experience! Scala isn't for the beginners.
> I’ve given irrefutable scientific evidence on why Scala will make you less productive.
Yeah, science! Those are just your opinions not scientific evidences. You're just don't know how to program in other languages(only in simple languages as java, javascript and python).
While you might not agree with his account of Scala, saying that folks who only know "simple languages" like "Java, JavaScript and Python" are unqualified to comment on Scala is just bizarre. Pray tell what you consider to be a language that would make a programmer worthy of Scala.
Has someone learned Scala and Go simultaneously ? This may seem a strange question - but I underwent this when I solved the Stripe CTF gitcoin challenge. I think that particular challenge was the most interesting because it branched into the leaderboard challenge.
I wrote the same code in Ruby-Celluloid, Python-subprocess, Scala-Akka and Go. When I did this, I came to an strange realization - I absolutely did not have fun writing Scala/Akka code as much as I did writing Go (minus the unused variable fascism).
Again, I'm not at all arguing the ecosystem of the JVM vs Go, but I just had a much better time grokking Go code than Scala/Akka - especially the package manager (pulling deps directly from github, etc.) I even sent in a patch for a go package ("gocmd" on github) barely a couple of hours after I first touched go for the first time in my life.
I dont have production worthy experience in either, so I dont have a strong opinion... but I really ended up wondering if Go makes Scala obsolete.
I was learning Scala and Go simultaneously. Hey, you forget to mention compiling time. Go is so fast that I just want to cry when I compile my Scala code.
Trying to drink the scala kool aid here at work, but I had a similar situation with Go and a freelance job. Went from 0 real experience to working code in very little time w/ go.
With scala I feel like I've spent more time waiting for it to compile than actually coding. Especially since we have been doing so much in Python, the switch back to compiled Java (with saccharine scala flavor) is like jumping back a decade in terms of productivity. Also, as you mentioned, the Go syntax is much easier to read, superficially just K&R C style with the types on the opposite side of the variable names.
Arent there people (like me) who will pay good money for a version of the Go compiler without that check ?
Does anyone know if I can disable it in the source code somehow and build a Go compiler (I doubt it though - if Go was never built with things like deadcode optimization because of this enforcement)
I found it a bit of a restriction, but ideally I'm not shipping code with unused variables, so why put them in. In the worst case I'd viciously comment things out, then uncomment them and add them back where I'd deleted once I figured out what the problem was.
If you chart out a software project from "blank file" to "write one line - code review by 8 people before merge", then Go is suited to the latter. I find myself writing a lot of malleable code when I'm prototyping and Go is really getting my way.
I dont dispute it is really useful (I worked for 6 years writing C, so I know about traps) but I really, really, really wish they would put a command line option to disable it.
You could build this by just removing the symbols that would trigger the check, either in a modified compiler or in a preprocessor. Go is pretty easy to parse so you should have an easy time of it.
If you want your unused symbols, you could insert "_ = unusedSymbol" instead.
I learned both at roughly the same time, and have put both into large-scale production. I had been a user of mostly C, Python, and a little Erlang before with applications in back-end systems. I reached a decent degree of proficiency in Go in a couple days. Scala I think I will not be great at for a few more months. With Go, I could grok large codebases in a matter of minutes. With Scala, I'm often bewildered by advanced patterns employed by some wizards. I think Scala lets you code-masturbate a lot more, if that's your thing. So it's important to have a culture of KISS or the wizards among you may sacrifice understandability for having some fun. But the advanced constructs occasionally allow you to do things that would be pretty ugly in Go. The JVM has nicer tooling built around it, and you will probably need to rely on it from time to time. As a non-ide user, getting scala projects to compile with sbt can take longer than writing some small applications. Go services have a much smaller memory footprint out of the gate.
I think I greatly prefer Go for simple services. But for projects that may require a lot more code and functionality, scala's abstractions may have a lot of value for you.
I've needed to tune JVM GC settings a lot, and I haven't yet run into major GC issues with Go. I'm sure there are some gotchas, but I've yet to run into them.
Scala is a functional programming language. Go is even more impractical than Java for FP. Scala runs on the JVM, Go does not. Depending on your views on these matters, you may lean towards one or the other, but it's still apples versus oranges.
Not at all. Getters and setters are a nasty code smell that generally arises when the author does not really understand OOP. You delegate to objects (tell, don't ask). Delegate to objects generally means person.goToWork() and not person.setIsAtWork(true). If your code is full of getters/setters you can probably refactor it to be far clearer.
A more non-conventional Java (but very far from crazy) is to use property accessors (person.name) instead of methods (person.getName()) for "data objects" (structs, really). Some people are very much against it as they believe it stops you being able to modify your object later, but I'd say modifying the access behavior of a struct (eg, O(1) to O(n) access) is even worse than forcing users to update their use of the object.
Anyway it's a far deeper topic than just "crazy java".
>A more non-conventional Java (but very far from crazy) is to use property accessors (person.name) instead of methods (person.getName()) for "data objects" (structs, really).
Yeah, it's a bit of a fallacy that requiring getters and setters (especially as simple pass-thrus) for simple properties is required for "good" OO (particularly that it maintains encapsulation). The bottom line is that providing both getters and setters makes the property mutable just as it would be via direct property access. Except now there's a performance penalty, as you mentioned.
And renaming a property typically means renaming the getters and setters anyway lest the property name no longer makes sense internally. Any good IDE will allow you to accommodate either refactoring (property name or accessor method names) with ease.
Initially, setters were also intended to allow the object to fire an event in the case that it's Observable or otherwise participating in a listener-style event system, such as that prescribed by the JavaBeans spec. But, in practice, that pattern is followed so rarely that it hardly merits forcing all of that baggage on every value object ever written.
The performance penality I'm talking about is far more tricky than just the little bit of overhead on a method vs a property. Take this simple data object as an example:
class Person {
public int age;
}
Now a 'best practice' is to create getters and setters:
class Person {
private int age;
public void setAge(int age) { this.age = age; }
public int getAge() { return this.age; }
}
This obviously makes the code uglier. This is done because maybe in the future you'd want to change the implementation of how age is stored inside the object. However, I think this is exactly where nasty performance bugs can slip in. Accessing 'age' or 'getAge()' are currently both O(1) operations with 'age' being slightly faster. However, 'age' will always be O(1) as guaranteed by the language, so using it inside a tight loop is fine. However, what happens if we modified our getAge() to be O(n) because we wanted to store age differently? eg:
class Person {
private List<Integer> subAges = ...;
public void setAge(int age) { ... }
public int getAge() {
int age = 0;
for (int subAge : subAges) {
age += subAge;
}
return age;
}
}
What we've done here is utilize our ability to change our getAge method without impacting anybody who is using our class. However, we've turned our getAge from O(1) to O(n) with absolutely no warning to anybody using our function. We've caused far more harm than simply requiring other developers to update their code - we've sabotaged the performance of all the users of all the software that uses our library.
So imo the 'benefit' you get from getters/setters is more of a danger than anything. If the implementation of a library changes enough that you need to change your data access objects, you should just release a completely new API anyway as all the assumptions made by users of your library are now right out the window.
> If functional programming is what you want, you can do it in your language.
This is a fallacy that gets repeated over and over, ad-nauseam. No, you can't do functional programming in any language. In Java it's more than just lack of syntactic sugar. Java's type system actively fights against functional programming. This is a bit like saying that you can do OOP in any language. Yes, you can have GObject in C. Yes, for Java there have been attempts like www.functionaljava.org ; but it sucks so badly that almost nobody does it, unless they are forced to do it.
In fact I challenge the author of this article to show me a piece of FP code that he wrote in Java by himself.
> What about all the wonderful things in the standard library? Yep, filter and map and fold operations on collections out of the box is nice. That the SDK uses Option instead of null is an improvement. These things are nice, but I generally get what I’m looking for by adding some libraries to core Java.
I do know Java's ecosystem and he must be speaking about Guava, as there's no other stable library for Java that has persistent data-structures. And Guava kind of sucks, so if you're looking for persistent data-structures, might as well implement them yourself, it's fun and it might open your eyes to what functional programming is ;-)
Speaking of Guava's Option, lets talk about how Guava's Option is not a Monad, or for those that don't know what that is, basically a context that implements map and flatMap with certain properties. Scala's Option also implements filter and fold, etc... which in regards to the purpose of a Monad, in the words of Erik Meijer, is to guide you through the happy path. Now that's a little closer to functional programming and speaking of Erik Meijer, people might be interested in what he thinks about Scala: https://twitter.com/headinthebox/status/438355100310831104
On the bad things he lists:
> Compile Time
Scala's type-system is much more static, leaving much less room for accidental bugs. Scala's compiler does things that in other languages you'd need to run specialized tools to get the same results or to write more tests. A single sentence or paragraph can't do it justice, but the big compile times are perfectly justified and this is coming from a developer that prior to Scala preferred dynamic languages with instant edit/reload cycles.
Besides, these times have been dropping as the core Scala devs have been making improvements, with another batch of optimizations coming in Scala 2.11. And incremental compilation in general works great. And I'm a developer, I have a good dev machine - if you don't have an SSD and at least 8 GB of RAM, then you've got no excuse.
> The IDEs
I've been using IntelliJ IDEA since a year ago and for people reading the rant exposed by the article - IntelliJ IDEA 13 for Scala is everything you'd expect an IDE to be and more. I never had problems with renaming things. I never had problems with finding all usages of a type. IntelliJ IDEA 13 works flawlessly for viewing the inheritance hierarchy and I'm doing the Cake Pattern which is freakishly heavy on the traits ;-) Other languages only dream about such awesome IDE support.
> Overuse of Operator Overloading
He complains about SBT, but I thought we were talking about the language and the standard library. Pity that he doesn't exemplify an instance in which "+" is overused.
> Implicit
He mentions implicit parameters, but exemplifies with implicit conversions. Implicit conversions are in fact considered experimental and starting with Scala 2.10 the compiler will issue warnings in case you're using them without allowing "language.implicitConversions", being replaced with extension methods by means of implic...
>Scala's type-system is much more static, leaving much less room for accidental bugs. Scala's compiler does things that in other languages you'd need to run specialized tools to get the same results or to write more tests
That is a bogus excuse. Languages with better type systems have faster compilers: haskell, clean, F# and especially ocaml. Paul Philips makes a pretty convincing argument that scalac is slow because it is a big mess.
Haskel's compiler is much slower than Scala. Ocaml's compiler is also slow.
F#'s type system doesn't do higher kinded types, or type classes, amongst other being much less sophisticated.
I'm really tired of hearing the Paul Philips argument. Scala 2.11 is a big refactoring addressing many of his complaints. Will that stop people from using the Paul Philips argument in conversations? Of course not, as many people weren't interested in his actual arguments.
Umm, no it isn't. I'm not sure I'm aware of a faster compiler. It's so fast most people don't even realise that they are running the byte code version (ocamlc) rather than the native code verison (ocamlc.opt).
GHC is faster than scalac, and GHC is the slowest haskell compiler. Ocaml optimizing compiler completely destroys scalac (and GHC), nevermind the bytecode compiler which is way faster than that. Being tired of reality doesn't change reality. When the single most knowledgeable person in the world on the internals of scalac talks about why scalac is slow, it is more likely that he is correct than some random scala fanboy on hn.
I never suggested he was leaving. I wasn't even referring to a talk he gave. I said he is easily the worlds foremost expert on scalac, and he does not think it is fast, or that it is slow because it has to do a lot of work other languages don't. He thinks it is slow because it needs to be re-written to not be a mess.
I never dismissed Paul Philips' arguments. In case you missed my not-so-subtle critique, I'm complaining about people referring to his presentation as a tool for bashing Scala, without having listened to those arguments. What's a "mess" anyway? Scala-js.org happened in a fantastic time-frame because it reuses Scala's reference compiler. How many languages can claim such performance?
People are also working on fixing many of the problems raised by Paul Philips, with Scala 2.11 being a result of that work. And oh look, Paul Philips is still on the contributors list, amongst many others: http://scala-lang.org/news/2014/03/20/release-notes-2.11.0-R...
You're doing both an appeal to authority for an otherwise unconstructive criticism (yours, not Paul's) and an ad-hominen in absence of actual arguments. Also for a random fanboy, at least I'm putting a real name behind my 2016 days old account ;-)
So can scalac. Many compilers have pathological performance cases. Just repeating "the sky is green" over and over won't make it so. It is well known and widely accepted that scalc is slower than ghc. You don't have to like it, or even accept it. But responding with nonsense strawman arguments as if I am bashing scala is pathetic even by hn standards. You made false claims, I pointed out that they are false. Quite simple.
>People are also working on fixing many of the problems raised by Paul Philips
Of course they are. Why do you think "people are fixing those problems" is evidence to support your claim that those problems don't exist?
"Not Knowing Scala Will Make You Less Productive", is the more appropriate title.
Scala is not, in my experience, a hit the ground running type language. You have to learn the ropes, discover the various gotchas (of which there are many), etc. before you begin to blow away your former self in terms of productivity.
I've only ever poked a little at Scala so my opinion isn't worth much, but what the OP says about operator overloading gels with my C++ coding experience. Everyone LOVES operator overloading when it's their own code doing the overloading. When you start dealing with other people's abuses of OOL, then it gets downright evil.
142 comments
[ 4.4 ms ] story [ 225 ms ] thread* Compile-time is slow * IDE support is more poor than Java * Overuse of operator overloading is confusing * Implicit confusing
I don't necessarily agree with all of these criticisms, but it's a very valid piece of "feedback" to the Scala community.
Odersky has taken an official stance against symbolic method names, especially in libraries, and many of the most famous offenders (Dispatch's absurd periodic table) are rightly ridiculed within the Scala community.
I don't have anything to add on implicits. They've certainly tripped me up a few times but generally it's just a matter of finding the right import, though I have been cursing Play's implicit JsValueWrapper the last few days.
If you give your methods bad names, it really is not the language's fault. You can probably find a way to make a bad API even if you are limited to a-zA-Z0-9 ...
If a library has an inscrutable set of method names blame the lib not the language.
The special operator rules allow library authors to create a "DSL" without using the (difficult) macro system. This almost never ends well.
The only similarity that Lisp and Scala have are that they are both functional programming languages[0].
Scala is a heteroiconic language. At least until recently, Scala didn't even have macros (I think they may have added that recently).
Scala is a nice language, but saying that Scala is somehow like Lisp is doing a disservice to both languages.
[0] Even the statement that Scala is functional is itself debatable - one can make the argument that it is "just" more purely object-oriented than Java, but that's a whole separate discussion.
Maybe we're just defining our terms differently, but the closest Lisp comes to a functional programming language is Clojure and before that Scheme.
This is not meant to deride Lisp in any way (Clojure is my language of choice, after all) - I think all Lisps enable a fundamentally unique way to reason about programs, but that's a characteristic of Lisp and not of functional programming languages.
More recently, people have confused "functional" with other features of languages like Haskell (sometimes called "purely functional"), leading to some confusion about what defines functional programming.
Here's an interesting post about the more recent changes in the phrase's meaning:
http://wcook.blogspot.co.uk/2012/07/day-functional-programmi...
I checked a few common definitions of homoiconicity and it seems like Scala is within the ruleset.
Isn't quoting necessary to "reify"/refer to the actual code as data?
I would really, really appreciate a Scala without all the crazy, but with all the brilliance. Or, you know, just a community that doesn't go out of its way to overuse all of that crazy.
Just drop the incomprehensible type declarations and the incomprehensible operators. Maybe add dynamic typing, even. Then you'd have a really nice language.
[1]: https://github.com/pathikrit/dijon
Eventually libraries that will come along that were intended to be used by humans. Sbt will disappear. Flowers will bloom, and the lion will lay with the lamb.
I know that the IDE support is lacking but this doesn't really bother me since I don't use an IDE with Play apps. I always use a text editor, since I find that IDEs tend to do a bunch of things badly, whereas a text editor and a terminal each do a single thing very well. There's nothing you said about the features of an IDE that I couldn't do just as well with a well-defined find-replace (besides variable extraction - not familiar with variable extraction.)
You can be productive in any language - Java, Scala. But I find that Scala's conciseness - the fact that I can do an operation on a whole collection of case classes using pattern matching and the collection API functions that would take 30 lines using classic Java - ends up making me more productive than I have been in those other languages. Maybe it's just me.
For someone learning Play & scala in general I find the IDE to be immensely helpful in showing my type information and valid auto-completes. Rather than constantly digging through documentation I can see that, for example, some flatMap will give me a list of (Id, User) tuples, so then I can call map( case(id, user) => user) ) (or just map(_._2)) and pull out the user objects to get my list of users from my list of tuples. This lets me focus on the business logic and not spend all my brain power tracking types. I don't think I would have survived my first foray into building complicated composite ResultSet parsers in anorm without the IDE.
I'm sure that as I gain more experience and all the functions become second nature I'll be able to track it in a text editor but for now I love my IDE.
At least, when I was working within play, it was painful enough to discourage me from test driving my code, especially if implicits were involved.
On one Play project we have ~160 test cases, including integration tests that spin up real Neo4j and Elasticsearch instances. Running the whole suite takes around 90 seconds. That would be far less if I did a better job separating unit and integration tests or mocking out the external dependencies.
As for integration tests those run via Specs2/Selenium as well but I rarely run them from my own machine as they are continuously running on Travis CI whenever I push to our repositories.
That is: - Type safe re-factorings (why would I give up on my type system to just go grepping around my code base?). To be honest I don't use variable extraction as often in my Scala code as I did in Java, but to have never used it makes me think you are severely undervaluing the whole type safe re-factoring universe. - Automated import statements. - Configurable code formatting.
The IDE space is improving dramatically in Scala, but I do think the Scala teams blessing of Eclipse was a mistake. They should have been writing more generic tools/hooks to empower their users in a wide variety of development setups.
Except with PHP you hit refresh and it is done. With play you wait 10 seconds and it is done. There is a huge difference.
eh? With incremental builds you should be seeing far more 1 second recompilations than 10 second recompilations.
If you're getting 10 second recompiles, the following help:
1) sub projects, it's an absolute must for non-trivial apps
2) use a 3rd party build system (say, GruntJS) for assets
Also, be sure to ;clean;compile prior to starting an incremental build with ~run (and of course, do this from a play> prompt and not bash, you want a warm JVM)
I can only really offer my experience, which is architecting and building out a 25kloc app and team to go along with. Mostly, because we avoided the 'clever' scala stuff as much as possible, things went well. Maven instead of sbt. Jetty instead of play. The only scala DSL we used was squeryl.
If I was doing it again, I'd probably rethink the use of scala. As helpful as it was, it was also a pain in places. Having to rewrite all our for loops was not cool. Case classes saves on boilerplate, but frankly you only write that stuff once, so it didnt really save us on a lot. Intellij elides most of the junky boilerplate (import statements, generating setters/getters, etc) in Java, so ...
Now a days with the advent of Java8, we have access to lambdas, function pointers/interfaces, and the functional stream system, I am interested to see how far one can get in just pure java. Java is the new scala it seems.
So the notion that every single last tiny class has it's own file hasn't ever been true (even if thats the coding style in a lot of code).
It's actually one of the biggest things I notice when I come back to java land.
I rarely do that any more these days so hopefully it'll become non-issue in the future for you.
You do realize that Scala doesn't have for loops, right?
http://stackoverflow.com/questions/1677419/does-scala-suppor...
On mutually recursive tail calls, yes, the runtime doesn't have support. Because it misses support for TCO, you're ready to call the JVM "godawful"? Might consider that .NET's tailrec support was basically a guideline that didn't work on 64bits .NET up until .NET 4.0 [1] and it's still not optimized, having a rather significant performance hit versus normal function calls.
For the JVM, a prototype for optimized tail recursive calls is in the works and given the attention that invokeDynamic received lately, I have no doubt it will be implemented for JDK 9 [2], especially given that people like Guy Steele are calling for it [3].
Either way, it's not so bad to implement mutually tail recursive calls by means of trampolines in Scala, especially given that you have an expressive type system at your disposal [4].
> you'd be in a pile of trouble if you messed up and your compiler ended up not doing it either
TCO is considered an optimization, not a guarantee, so if you want it to do a TCO by contract, then an annotation makes sense, no?
[1] http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11...
[2] http://openjdk.java.net/projects/mlvm/subprojects.html
[3] http://i.imgur.com/5X3VwOy.png
[4] http://blog.richdougherty.com/2009/04/tail-calls-tailrec-and...
Some JVMs such as Avian support this feature, so they may not be godawful. I haven't used them much, so I don't know.
> For the JVM, a prototype for optimized tail recursive calls is in the works and given the attention that invokeDynamic received lately, I have no doubt it will be implemented for JDK 9 [2], especially given that people like Guy Steele are calling for it [3].
This is great to hear, thanks for telling me about it :)
It sounds like I will have a better time in JVM-land next time, if I ever have a reason to go back.
> TCO is considered an optimization, not a guarantee, so if you want it to do a TCO by contract, then an annotation makes sense, no?
In JVM-land, this is the case, which is why I said one should be careful to use the annotation. I don't have a problem with using the annotation. I do have a problem with TCO not being guaranteed in the language spec (like Lua), or at least supported by popular runtime+compiler combinations (like C++).
I have confidence to advise building real businesses with Scala stack and not looking like an irresponsible guy who just wants to play with the latest and shiniest stuff hazarding a company's business. I also see how Typesafe is focusing on solving bad parts: compiling time, stability, etc.
You can also stay away from advanced / theoretical / crazy parts of Scala most of time. You don't need to use Scalaz, advanced type system features etc. There are also immature libraries, toys and proof-on-concepts, but you cannot blame Scala for your choice.
The parts that make it worth using in the first place?
>You don't need to use Scalaz, advanced type system features etc
Might as well stick with java then. You're not getting the benefits of scala vs java, but you are still paying the costs like compile times and poor tool support.
Sticking with Java you lose both the expressive Scala features and some good frameworks without Java burden.
Btw under "advanced parts" I didn't mean "everything above Java". I enjoy immutability, collections, case classes, pattern matching, first class functions, lambdas, terse syntax not considered them "advanced parts". Advanced parts are all those lenses, recursive types, type lambdas, you know.
What it does wrong is when copy/pasting code or when moving a class/trait to another file/package, it sometimes misses the imports for the implicits that the code is using. You can't really blame it, since an imported implicit is not hard-wired in the same way an explicit reference or type usage is. Depending on your perspective, this may be a feature and not a bug :-)
Either way, IntelliJ IDEA gives awesome in-editor error highlighting and you also have Scala's compiler to double-check things for you, so you really don't have to double-check the IDE's work, except in cases where there are problems.
> The Java-to-Scala tool emitted code that would never have compiled on any version of the Scala compiler.
It's pretty hard to translate from Java to Scala and you're right that it doesn't work. On the other hand, idiomatic Java code is pretty freaking far from idiomatic Scala code and I think you should either leave that Java code as is (mixed projects are easy to configure) or you should translate it in idiomatic Scala code by hand, a task that no transpiler could do.
This does sound like a feature and not a bug, yes.
> It's pretty hard to translate from Java to Scala and you're right that it doesn't work. On the other hand, idiomatic Java code is pretty freaking far from idiomatic Scala code and I think you should either leave that Java code as is (mixed projects are easy to configure) or you should translate it in idiomatic Scala code by hand, a task that no transpiler could do.
I agree, but some of the team used IntelliJ's make and apparently our particular project configuration had trouble with Java in some projects, so where there wasn't much Java the solution we went with was to move it to Scala. There were other more reasonable solutions available like "Fix the config" or "Just use xsbt bro", but it wasn't my call.
Which I already conceded as being in Java 8. Not sure what your point is.
Tool support is outstanding with IntelliJ
On macrolevel, the obvious thing is that you can separate your projects. I also have some expectations for upcoming Scala release.
But that's a really good question to ask anyone from Twitter and Co.
In this lengthy [post|comment], I’ll share my thoughts and opinions on [THING IN COMPUTING, TiG hereafter] . . . Using a cavalcade of flawed data; logical fallacies; biased opinion; startling lack of citations; and basic nonsense, I will convince you that using [TiG] will make you less productive. I will finish with an underwhelming and unexciting conclusion. You have been warned.
Think of it! "I'm offering my thoughts here under Ahmdal's Condition, of course . . ." "Well, I think you're starting from Ahmdal's Condition . . ." "That works under Ahmdal's Condition, but assuming stricter conditions . . ."
Honestly, it's genius. If I had a magic meme wand, this guy would be famous by the end of the day.
But.
Even first hand anecdotal evidence has its limits. It really needs to be blatant to be significant. Second hand anecdotal evidence is even worse. If the phenomenon you want to catch is subtle, you generally a good deal of reliable data. That generally means something "scientific".
Ah, the dreaded double standard. Easy trap. Personally, I avoid it by trying to have objective criteria. I end up with crude and imperfect measures (LOC count, number of defects…), but at least they're not too biased.
> personal evidence is less strong than scientific evidence.
Actually, this is not necessarily true about first hand personal evidence. While a host of biases are out to cloud your judgement, science can be weak for two reasons: (i) the studies may not amount to much evidence, either because the controlled experiments are also artificial, or because there may not have been much of them (it is quite expensive to do the same project multiple times with arguably similarly skilled teams), or both. (ii) What applies to the majority of people may not apply to you specifically (though you'd better have strong evidence as to why this is the case).
Now, second hand personal evidence… that's much harder, because (ii) doesn't apply, you also have to trust whoever is telling you the story, and this story hold far, far less information than what you would have gathered by living it yourself. Still, it may yet be stronger than sufficiently weak scientific evidence.
Now, a blog post by a random programmer? Okay, that one is always weaker than science.
Ahmdal is not the OP :/
http://en.wikipedia.org/wiki/Amdahl's_law
So much experience! Scala isn't for the beginners.
> I’ve given irrefutable scientific evidence on why Scala will make you less productive.
Yeah, science! Those are just your opinions not scientific evidences. You're just don't know how to program in other languages(only in simple languages as java, javascript and python).
http://paulgraham.com/disagree.html
I wrote the same code in Ruby-Celluloid, Python-subprocess, Scala-Akka and Go. When I did this, I came to an strange realization - I absolutely did not have fun writing Scala/Akka code as much as I did writing Go (minus the unused variable fascism).
Again, I'm not at all arguing the ecosystem of the JVM vs Go, but I just had a much better time grokking Go code than Scala/Akka - especially the package manager (pulling deps directly from github, etc.) I even sent in a patch for a go package ("gocmd" on github) barely a couple of hours after I first touched go for the first time in my life.
I dont have production worthy experience in either, so I dont have a strong opinion... but I really ended up wondering if Go makes Scala obsolete.
With scala I feel like I've spent more time waiting for it to compile than actually coding. Especially since we have been doing so much in Python, the switch back to compiled Java (with saccharine scala flavor) is like jumping back a decade in terms of productivity. Also, as you mentioned, the Go syntax is much easier to read, superficially just K&R C style with the types on the opposite side of the variable names.
Does anyone know if I can disable it in the source code somehow and build a Go compiler (I doubt it though - if Go was never built with things like deadcode optimization because of this enforcement)
I dont dispute it is really useful (I worked for 6 years writing C, so I know about traps) but I really, really, really wish they would put a command line option to disable it.
Very very handy...
If you want your unused symbols, you could insert "_ = unusedSymbol" instead.
I think I greatly prefer Go for simple services. But for projects that may require a lot more code and functionality, scala's abstractions may have a lot of value for you.
I've needed to tune JVM GC settings a lot, and I haven't yet run into major GC issues with Go. I'm sure there are some gotchas, but I've yet to run into them.
A more non-conventional Java (but very far from crazy) is to use property accessors (person.name) instead of methods (person.getName()) for "data objects" (structs, really). Some people are very much against it as they believe it stops you being able to modify your object later, but I'd say modifying the access behavior of a struct (eg, O(1) to O(n) access) is even worse than forcing users to update their use of the object.
Anyway it's a far deeper topic than just "crazy java".
Yeah, it's a bit of a fallacy that requiring getters and setters (especially as simple pass-thrus) for simple properties is required for "good" OO (particularly that it maintains encapsulation). The bottom line is that providing both getters and setters makes the property mutable just as it would be via direct property access. Except now there's a performance penalty, as you mentioned.
And renaming a property typically means renaming the getters and setters anyway lest the property name no longer makes sense internally. Any good IDE will allow you to accommodate either refactoring (property name or accessor method names) with ease.
Initially, setters were also intended to allow the object to fire an event in the case that it's Observable or otherwise participating in a listener-style event system, such as that prescribed by the JavaBeans spec. But, in practice, that pattern is followed so rarely that it hardly merits forcing all of that baggage on every value object ever written.
So imo the 'benefit' you get from getters/setters is more of a danger than anything. If the implementation of a library changes enough that you need to change your data access objects, you should just release a completely new API anyway as all the assumptions made by users of your library are now right out the window.
This is a fallacy that gets repeated over and over, ad-nauseam. No, you can't do functional programming in any language. In Java it's more than just lack of syntactic sugar. Java's type system actively fights against functional programming. This is a bit like saying that you can do OOP in any language. Yes, you can have GObject in C. Yes, for Java there have been attempts like www.functionaljava.org ; but it sucks so badly that almost nobody does it, unless they are forced to do it.
In fact I challenge the author of this article to show me a piece of FP code that he wrote in Java by himself.
> What about all the wonderful things in the standard library? Yep, filter and map and fold operations on collections out of the box is nice. That the SDK uses Option instead of null is an improvement. These things are nice, but I generally get what I’m looking for by adding some libraries to core Java.
I do know Java's ecosystem and he must be speaking about Guava, as there's no other stable library for Java that has persistent data-structures. And Guava kind of sucks, so if you're looking for persistent data-structures, might as well implement them yourself, it's fun and it might open your eyes to what functional programming is ;-)
Speaking of Guava's Option, lets talk about how Guava's Option is not a Monad, or for those that don't know what that is, basically a context that implements map and flatMap with certain properties. Scala's Option also implements filter and fold, etc... which in regards to the purpose of a Monad, in the words of Erik Meijer, is to guide you through the happy path. Now that's a little closer to functional programming and speaking of Erik Meijer, people might be interested in what he thinks about Scala: https://twitter.com/headinthebox/status/438355100310831104
On the bad things he lists:
> Compile Time
Scala's type-system is much more static, leaving much less room for accidental bugs. Scala's compiler does things that in other languages you'd need to run specialized tools to get the same results or to write more tests. A single sentence or paragraph can't do it justice, but the big compile times are perfectly justified and this is coming from a developer that prior to Scala preferred dynamic languages with instant edit/reload cycles.
Besides, these times have been dropping as the core Scala devs have been making improvements, with another batch of optimizations coming in Scala 2.11. And incremental compilation in general works great. And I'm a developer, I have a good dev machine - if you don't have an SSD and at least 8 GB of RAM, then you've got no excuse.
> The IDEs
I've been using IntelliJ IDEA since a year ago and for people reading the rant exposed by the article - IntelliJ IDEA 13 for Scala is everything you'd expect an IDE to be and more. I never had problems with renaming things. I never had problems with finding all usages of a type. IntelliJ IDEA 13 works flawlessly for viewing the inheritance hierarchy and I'm doing the Cake Pattern which is freakishly heavy on the traits ;-) Other languages only dream about such awesome IDE support.
> Overuse of Operator Overloading
He complains about SBT, but I thought we were talking about the language and the standard library. Pity that he doesn't exemplify an instance in which "+" is overused.
> Implicit
He mentions implicit parameters, but exemplifies with implicit conversions. Implicit conversions are in fact considered experimental and starting with Scala 2.10 the compiler will issue warnings in case you're using them without allowing "language.implicitConversions", being replaced with extension methods by means of implic...
That is a bogus excuse. Languages with better type systems have faster compilers: haskell, clean, F# and especially ocaml. Paul Philips makes a pretty convincing argument that scalac is slow because it is a big mess.
F#'s type system doesn't do higher kinded types, or type classes, amongst other being much less sophisticated.
I'm really tired of hearing the Paul Philips argument. Scala 2.11 is a big refactoring addressing many of his complaints. Will that stop people from using the Paul Philips argument in conversations? Of course not, as many people weren't interested in his actual arguments.
Umm, no it isn't. I'm not sure I'm aware of a faster compiler. It's so fast most people don't even realise that they are running the byte code version (ocamlc) rather than the native code verison (ocamlc.opt).
He doesn't think the language is perfect (no one does) but he doesn't think any other existing language meets his standards either.
I never dismissed Paul Philips' arguments. In case you missed my not-so-subtle critique, I'm complaining about people referring to his presentation as a tool for bashing Scala, without having listened to those arguments. What's a "mess" anyway? Scala-js.org happened in a fantastic time-frame because it reuses Scala's reference compiler. How many languages can claim such performance?
People are also working on fixing many of the problems raised by Paul Philips, with Scala 2.11 being a result of that work. And oh look, Paul Philips is still on the contributors list, amongst many others: http://scala-lang.org/news/2014/03/20/release-notes-2.11.0-R...
You're doing both an appeal to authority for an otherwise unconstructive criticism (yours, not Paul's) and an ad-hominen in absence of actual arguments. Also for a random fanboy, at least I'm putting a real name behind my 2016 days old account ;-)
So can scalac. Many compilers have pathological performance cases. Just repeating "the sky is green" over and over won't make it so. It is well known and widely accepted that scalc is slower than ghc. You don't have to like it, or even accept it. But responding with nonsense strawman arguments as if I am bashing scala is pathetic even by hn standards. You made false claims, I pointed out that they are false. Quite simple.
>People are also working on fixing many of the problems raised by Paul Philips
Of course they are. Why do you think "people are fixing those problems" is evidence to support your claim that those problems don't exist?
Scala is not, in my experience, a hit the ground running type language. You have to learn the ropes, discover the various gotchas (of which there are many), etc. before you begin to blow away your former self in terms of productivity.