Live data from Hacker News

Scala – 1 Star – Would Not Program Again

overwatering.org

311–320 of 324 posts

Re: Scala – 1 Star – Would Not Program Again

#311

Earlier quoted context omitted.

Languages like Ruby and Python allow for expressive, high-level customization, metaprogramming, and DSL creation. However, especially in the latter, the potential chaos is curbed by a strong culture and encouragement of self restraint, readability, and simplicity. From the sound of it, this is not so true for Scala.

I'm really curious of what "sound" you're talking about. I've been working with Scala full-time for the past 2 years. Prior to that I worked with Perl, Python and Ruby and I still work with these languages for quick scripting or if the codebase demands it. Scala code-bases tend to be based to a higher degree on good engineering practices. Scala itself is a much more static language than a language like Java, hence it…

Good engineering practise?

1. Lack of documentation

2. Breaking backwards compatibility

3. Opaque error messages

4. Encourages ad-hoc syntax that makes sense to one person (or team) but does not to the next -- maintenance nightmare.

5. Lack of general stability in language and libraries serving to confuse the eco-system.

Hmmm....

Re: Scala – 1 Star – Would Not Program Again

#312
post #23

Earlier quoted context omitted.

I'll echo all of this (minus scalaz, we don't use that). I'll give an example of the power of Scala's type system. When I first convinced one of our founders to give Scala a try, he used it to write the first pass of our analytics service. He'd never written Scala before but once it compiled, it ran correctly on the first try, that's the power of its type system.

Having never used Scala before, does its type system provide details about errors that other languages do not? Watching a compile fail because of an incorrect type is not something I have run into very often, if ever, in other languages that provide similar type systems. I mean mistakes can happen and if the type system can catch it for free, so to speak, that is great. I'm not about to argue that it is completely us…

Scala has dependent type support, so, yes, it is quite more powerful than most languages in widespread use. You can look at the Shapeless library to see that at work.

However, that is not really what's going on... though Scala type system, even without dependent types, is strictly more powerful that Java's, it really comes down to the ease of use: Scala programmers tend to use types liberally (which was one of the criticisms of the article), and that is part of the "magic".

Part of this is how easy it is to define a type: it can be as short as a single line. So you'll see way less String types in Scala, for instance, or "one type to do it all" like the article wanted for HTTP. Instead, you get many types, in which invalid states are not possible and, therefore, getting the types right is enough to ensure there are no invalid states.

Likewise, the partial type inference offered by Scala makes it possible to not worry about all these types: the compiler knows what type you got, and knows whether it can be used the way you are using it, so you don't have to keep looking up types to get things accomplished, but still get to have the types.

Another part is that Scala support higher order types, something not supported by Java, which makes them more useful. That's what allows monads & companions come in and make an appearance -- it's not that you can't write a monad in Java, it's just that you can't abstract over them.

The final part is emphasis on immutability. When you stick to immutable objects representing valid states, the space for errors not caught by the type system is greatly reduced.

Let's get back to the headers, then. First, yes, you are allowed to add arbitrary headers (which is supported by Spray through RawHeader, something it took me 30 seconds to find out, even though I have never used Spray and have little familiarity with it), but section 14 of RFC 2616 has a nice list of standard headers and the rules they are expected to abide by, so let's have them.

And if you have a header, and it is a X-Forwarded-For, isn't it reasonable to expect the value to be a valid remote address? It is supposed to be a valid remote address, after all. So, if you ask for this header, should you simply get a string that may or may not be actually valid, or should the type system give you an Option that may contain Some valid header, or None, therefore ensuring that you don't just assume you are getting the right thing? And if you get something and retrieve the value, is it preferable to just get a string, that might lead to some ad hoc parsing of the address, or some actual type where you can easily retrieve information in a safe manner?

The Scala community will usually think that yes, that's a good idea, and design the APIs accordingly.

Re: Scala – 1 Star – Would Not Program Again

#313
There's a lot that could be criticized about Scala, but that article is a criticism of the author, for me who actually knows something about Scala.

It starts with a criticism of a build system that is most likely SBT. Now, for all its strengths, you could not pick an easier target than SBT if you wanted to bad mouth a piece of Scala software, but what we get is:

* It is slow to recompile the build definition (true, not the most complex build files I ever saw ever took anywhere near that time); * I didn't bother to learn the syntax (or what was going on).

Is that it? If all you have to complain about SBT is this, then you never actually made even a passing attempt to learn to use it. That doesn't make me much confident about the author...

Next, the author has been writing Scala code for the past two weeks. Scala is not, I argue, as complex as people make it to be, but it has enough different concepts than what most other languages offer that you simply don't pick it up in two weeks, just like you didn't learn your first programming language in two weeks.

If you come from Java, two weeks of Scala let you use Scala like Java: you'll produce working software, though not in any idiomatic style. Well, we pick later on that the team is using Spray, and Spray is a very idiomatic library. You do have to unlearn many habits to pick it up, and the author doesn't seem interested in unlearning anything he "knows".

He picks Scala because, hey, there were doing XSL and doing XML processing, so Scala must be good at it, right? Well, actually, no, but I can see why one would think that, and also why one would be disappointed that it actually isn't, but picking the wrong tool doesn't mean the tool is bad: it's just not the tool for that.

So we go to TDD, where he comes up on Scala awful compile times (which troubled him with SBT before). That is a problem that Scala community has faced, and it has produced solutions to that problem. Specifically, it has adopted SBT, a build tool which can compile incrementally (and automatically on change), and even execute just the tests that are affected by a change (automatically as well).

Of course, the author, having chosen Scala, decides to ignore the existing solutions and picks up Gradle, which supports none of this. Now, Gradle is a very nice build system, but, again, the author picks the wrong tool and proceeds to blame the wrong thing from it.

Next, the author proceeds to have problems with libraries -- problems somehow not shared with the rest of the community (see comments by other Scala users). He mentioned stability problems, and then mentions two pieces of software with excellent documentation, extremely stable, and supported across a broad range of versions of their dependencies.

Now, choosing Spray when you are not familiar with Scala was a terrible decision, and I can well see where the author had trouble using it -- while not agreeing there's any problem with Spray itself. Having trouble with Specs2, however, makes me seriously doubt his abilities -- if he truly had trouble with it.

Next he proceeds to some discussion of simplicity, and I'd grant that Scala is not simple. However, he ties that to a lack of regularity, which is interesting in that Scala is highly regular, much more so than Ruby. It just allow different things than the languages he is used to, so it looks different.

I can buy "looks different" -- yes, it does. But the author's inability to realize how regular it is just goes to show that he has a very, very poor knowledge of Scala. That's not a problem with Scala, it's just that he didn't learn Scala, and it keeps showing.

So, having not learned Scala, he tries to accomplish something that required a specific Scala knowledge he lacked and fails. And somehow that's Scala's fault and Spray's fault, not his.

Well, I admit it: if you don't learn Scala, it is very difficult to program in Scala. That's certainly not the case with PHP, for example, but I have certainly struggled with rather simple tasks in Ruby when trying to write code in Ruby without learning it. I just never blamed Ruby for it.

Next, "everything is a type". I disagree that this is in any way a problem -- if you are going to complain about that, how about just writing "Scala is a statically typed language" and leave it at that? We all knew that, didn't we?

So, having chosen a statically typed language, he dislikes the fact that it actually tries to use types? Weird, but at least he doesn't make it a problem of Scala itself.

On the other hand, it took me thirty seconds to find RawHeader, which allows arbitrary headers, which indeed would be a weird thing to be missing. It's right there, among the other headers. Among, say, Origin and either Access-Control-* headers, which happen to be the CORS headers, all of which appear in the API docs, so what gives?

Maybe they are new headers? Well, the CORS headers are new, if not that new, but maybe the article refers to something that happened months ago. The raw header is there for quite a while, as you can see for yourself here: https://github.com/spray/spray/blame/master/spray-http/src/m...

At this point, I don't even know where the author is coming from, that he failed to spot this. It is certainly not Spray's fault, much less Scala's.

Next comes a rant on lack of H-M type inference. Well, we all would have liked to have more type inference (without making the compiler even slower!), but separate compilation, subtyping and full type inference is not a solved problem. Which doesn't mean we can't gripe about it.

But there's a damning comment among it: the error message he describes in his "workflow". Hey, Scala infers the return type, so he doesn't need to add it, unless he's doing recursion of calling overloaded methods. If he were doing that, however, the error message would be different.

What the error message says, however, is that he is using procedure syntax -- that is, a method returning void in C/Java parlance -- when he actually intended the method to return something. He doesn't need to add the type, he just needs to use the correct declaration:

def method() { body } // procedure (unit-returning method)

def method() = expr // function

He spent two weeks programming in Scala, then went on to write a blog about it, but he still hasn't figured out a simple detail like this, despite the compiler telling him what the problem is?

Yes, beginners might well struggle with this oddity, but for two weeks??? And despite having fixed it throughtout the program? Really?

Now, detour briefly through long vs int, which I actually agree with, but saying he was "reminded" of it shows a complete lack of familiarity with statically typed languages.

Again, fine that you don't like statically typed languages, though I think one ought to first learn one of them before criticizing, but you could start and end your post with "I don't like statically typed languages".

Then there are other issues which he enumerates but don't describe, and which I can only disagree with. Horrible repetition required by case classes? Err, what repetition?

So, in the end, it seems that what the author really wanted to say is: I don't like statically typed languages, and I tried to use one for the wrong reasons, in the wrong way, without learning it, and failed. No need to blame Scala for his bad decisions.

Re: Scala – 1 Star – Would Not Program Again

#314

The section on HTTP headers and typing is a little concerning to me. I've been making rust-http recently and (before I was aware of Spray) I felt strongly about the typing. So, I'd like to discuss this. Am I wrong after all? Here clearly is someone that disagrees with me. I think I should probably write up a long blog post on the topic explaining my reasoning and so forth. rust-http is, at present at least, rejecting…

My main concern is the last sentence of the section you quote. There's tension between headers which are well-known and standardized (either formally or through de-facto wide use), and so are amenable to being properly modelled, and headers which are not well-known or which may not even exist yet. Hence, I think, his comment about CORS. And I'm not sure there's a good solution. The obvious approach, as you already kn…

The thing is, support for arbitrary header is there: RawHeader, defined as a pair of header name and header value strings.

Re: Scala – 1 Star – Would Not Program Again

#315

Earlier quoted context omitted.

I'm really curious of what "sound" you're talking about. I've been working with Scala full-time for the past 2 years. Prior to that I worked with Perl, Python and Ruby and I still work with these languages for quick scripting or if the codebase demands it. Scala code-bases tend to be based to a higher degree on good engineering practices. Scala itself is a much more static language than a language like Java, hence it…

Good engineering practise? 1. Lack of documentation 2. Breaking backwards compatibility 3. Opaque error messages 4. Encourages ad-hoc syntax that makes sense to one person (or team) but does not to the next -- maintenance nightmare. 5. Lack of general stability in language and libraries serving to confuse the eco-system. Hmmm....

> 1. Lack of documentation

Again, in my experience, the documentation in Scala land is very good. The standard library has a really good API documentation, also checkout the documentation project at http://docs.scala-lang.org/ plus there are several very good books available; then there are the libraries in Scala's ecosystem, like Play2, or Akka, or Slick for example that do have good documentation. The online documentation for Play2 does not match the online documentation for Ruby on Rails or Django, but it's newer and it's improving and I remember a time when Rails was several years old and lacked online documentation. I did find undocumented features in Play2's online documentation, but nothing that couldn't be solved with a question on its mailing list. These are open-source libraries, with strong communities that communicate a lot on mailing lists, you know.

The great thing about Scala is that you can also use any Java library you want and wrapping Java libraries in Scala-ish interfaces is actually easy and a great learning experience. I wished you'd be more explicit about this point, because for me I don't feel like there is a lack of documentation.

> 2. Breaking backwards compatibility

This is a point that comes up a lot, but I don't think it's that important for people actually using Scala. Scala is a compiled language, the libraries get distributed / deployed as compiled bytecode packaged up as Jars. This means that breaking compatibility is really easy, as all you have to do is to change an interface, like adding, removing or changing the signature of a method and boom, all code that depends on that interface needs to be recompiled, even for code that's not using the method in question. Dynamic languages that get interpreted or compiled on-the-fly, like Python or Ruby, are distributed as source-code. So by their nature don't have this disability.

The alternative to breaking backwards compatibility in Scala is to freeze the standard library. Personally that's not a compromise I want, because for this very reason Java's standard library is full of idiosyncrasies, broken interfaces, broken behaviour and various other artefacts going back to Java 1.0, that were never fixed in order to preserve backwards compatibility.

Scala has improved a lot though, compared to the 2.8 days. Nowadays you've got a guarantee that minor versions aren't breaking backwards compatibility. Code compiled with Scala 2.10.0 is guaranteed to be compatible with Scala 2.10.3 at least. The next version free to break compatibility with 2.10 is Scala 2.11. The tooling in Scala's ecosystem, like SBT, is also friendly to supporting multiple versions. To compile, test and deploy versions for multiple Scala versions is often just a configuration change, assuming you don't use APIs that aren't available in older Scala versions, in which case the back-ports are hard to accomplish in any language.

> 3. Opaque error messages

That's in the eye of the beholder. Sometimes the error messages are not so good, especially when triggered by the new macro support in Scala 2.10, but you know, those macros are experimental and improving by leaps and bounds. 90% of the time I have no problem understanding the given error messages and many times you get really helpful errors or warnings about code that you think it's correct, but isn't, like when pattern-matching on an ADT and missing a case. And I prefer opaque compile-time error messages to subtle or non-deterministic runtime error messages. In Python I used to suffer from null pointer exceptions all the time. In Scala null pointer exceptions are very rare.

> 4. Encourages ad-hoc syntax that makes sense to one person (or team) but does not to the next -- maintenance nightmare.

This is a thing that gets repeated by people that haven't used Scala, either personally or in a team. The syntax, even for libraries that go over the top on DSLs, is quite sane. It's much saner than in Ruby. And I prefer the succinctness of it, compared to code written in Java that often feels like a puke of useless crap that you have to read through in order to get to the bottom of whatever the piece of code you're reading actually does. Code written in more powerful languages feels like being harder to read, simply because each line of code does more.

It's not the syntax that's the problem dude. Having worked with Scala in a team, the real problem are the functional programming concepts involved. In Scala you end up using recursion, error-handling without exceptions (e.g. Either/Option/Try), lazyness, monads, applicative functors, iteratees or other forms of doing stream processing and the list can continue. But it's hard because most developers are not familiar with these concepts, because many of the techniques involved are like death by a thousand cuts to apply in more mainstream languages.

Then there's the type system. Scala is much more static than languages like Java or C#. It's great for users of properly designed libraries. It's not so great for language designers themselves, as people sometimes end up jumping the shark on static type safety, digging themselves into a corner. When you're seeing libraries that are hard to read because of all the generic types involved, well, on the flip side, Scala allows you to do things that are impossible to do in Java. That's why you're seeing a lot of type-casts in Java, whereas in Scala type-casts are more like an anomaly. Plus, Java uses wildcards for covariance/contravariance, which suck. Java libraries are often not generic because generic types in Java suck so badly.

> 5. Lack of general stability in language and libraries serving to confuse the eco-system.

I think at this point, you're being redundant, for the lack of better criticism. I disagree of course.

Re: Scala – 1 Star – Would Not Program Again

#316

I'd say a lot of the critiques are fair but quite exaggerated. I work on a large Scala codebase and yes, the compile times for a fresh start across the codebase are very long, but TDD-type loops are very short, because you're generally waiting for two files (your test target and your test code). Still, the compiler performance in Scala is perhaps my chief criticism, though hardly a show-stopper. As codebases in any l…

An often overlooked fact is that a lot complexity in the Java world is in the frameworks. You can express many things directly in Scala, for which you would use a Java framework a bunch of annotations (without compile time semantics).

Re: Scala – 1 Star – Would Not Program Again

#317
post #140

Earlier quoted context omitted.

> Scala is on my "will not work with" list of languages/technologies Just curious, what are the some languages/platforms you like or enjoy using? (Mine are Python, Erlang and Go for ex).

Hobby wise: Haskell, Rust, Nimrod, Haxe Shipping code: Go, Erlang, C++11 (avoiding legacy), F# (with Xamarin) I program in many more, but those are probably my top 8 right now.

I'm curious as to whether you have shipped or have thought about shipping code in Haskell and why or why not. Rust I'm assuming is too new for that to be an option.

Re: Scala – 1 Star – Would Not Program Again

#318
Horribly misinformed. Author didn't learn basics of the language - "val" vs "def" is very fundamental - constant vs. function. Scala does not use Hindley-Milner.

Legit issues: compile time (of course), library docs (maybe), bad HTTP header API (maybe), tooling (maybe). I thought the automatically generated (doxygen style) library docs were fine when I was playing with Scala two years ago.

Re: Scala – 1 Star – Would Not Program Again

#320

Earlier quoted context omitted.

C# does that too. It's called LINQ and it's very popular.

It's NOT called LINQ in C#. You are probably referring to "LINQ to SQL" which is different and significantly less popular technology than LINQ.

Or "LINQ to EF" which you can suppose it stable just when working with "MS SQL Server".
Post reply on HN