1. 54
  1. 32

    I have no experience with Scala, but my overwhelming sense of the language and the community is that the whole thing is a mess. So I didn’t consider it, and still wouldn’t.

    Ouch. Regardless of whether it is true, outsiders getting such an impression is not good for any language/library/community.

    1. 24

      It’s the impression I get, too. I used to be super-excited about it, but then Kotlin got a lite version of most of the things I was excited about, and (AFAIK) they’ve been working on the “actual proper version” of Scala for about 5 years now, with no end in sight. And last time I looked into it even Rust developers were making fun of the compile times.

      1. 14

        Can second, third?, this. Never used scala. Know very little about it. I have the impression its terrible based upon my limited readings on the internet.

        scala has a serious image problem.

        1. 10

          At a previous job, I used Scala as one of my primary development languages, mostly maintaining an existing scala codebase. My general impression of Scala was that it was an okay-enough language if you stuck to writing functional-style code in it. The fact that it simultaneously supported object-oriented workflows, as well as interoperability with existing Java code made the language big and complex (although the ability to use the existing Java library ecosystem is of course quite useful).

          I liked that it made pervasive use of Option types in lieu of nulls everywhere (although the language still supported null, for Java interoperability I assume) - but for whatever reason, it really wanted to use Java-style exceptions instead of saner Result types. Its monadic for construct (pretty similar to Haskell do-expressions) was a genuinely neat idea. Implicit parameters are a terrible idea and I wasted many hours debugging confusing compilation errors around them. And a lot of the tooling (sbt and various plugins) was slow and/or buggy, in my experience. Note that I was using Scala before the 3.0 upgrade, which I understand has made some significant improvements.

          All in all, I didn’t hate Scala, but neither was I particularly enthused by it. I would absolutely prefer to write code in Rust than Scala unless I really needed to run code on the JVM for some reason - and even then, I would spend some time looking into Kotlin first, since that language seems to have a better reputation.

          1. 3

            I use scala at work, it’s great. Compile times are a bit long though.

            1. 2

              Seconded. I enjoy the experience of writing code in Scala. Compile times can be annoying sometimes.

            2. 1

              Can you go into the specifics?

              1. 1

                About what exactly? Like I said I don’t really know much scala. I’ve just heard it’s a “terrible” language.

                I’m not passing judgement. I’ve never used it. Just the feeling you get based on what you see on the internet.

            3. 7

              That was a gratuitous dismissal that really have no place when it comes to make engineering decisions. The author didn’t disclose how much they looked into it or why/how it is a mess. It’s a versatile language with very sweet compact syntax and above average documentation. Well, at least it was when I used it almost a decade ago.

              I do however a few concerns about it, perhaps it is this kind of thing the article refers to:

              • Too much syntax sugar, too many ways of doing the same thing. This has proven to be counter productive (cough cough perl) for language productivity and ultimately adds little value. The same simple problem solved by different developers can look almost like two different languages.
              • Many years ago, I picked scala for a web crawling project because it had a support for concurrency using actors built right in the standard api. This allowed for tremendous flexibility and control of concurrency threads and resources. But the thing crashed unexplainably after half an hour or so. I couldn’t figure out why, looked everywhere, posted the problem in the most prominent community communication channels but never got any help. I eventually had to rewrite the crawler using python and eventlet. A couple of years after, the problem was mentioned as a fixed bug on the release notes of a version of the language. This was a huge disappointment. The core api had unusable concurrency primitives and no one knew about it. A couple of more years passed and the actors support was dropped in favor of a third party library (akka). I take it it was poorly written and full of bugs. for a language with so much emphasis on its theoretical and academic foundations, this is very embarrassing and discrediting. No offence for the good people behind it.
              • It was positioned to offer a great deal of advantages over java, but in my opinion didn’t achieve critical mass and, with google announcing first class support for kotlin in android, I believe the window of opportunity is closed and all we will see from now on is a language decreasing in popularity and momentum.
              1. 5

                above average documentation

                I’d call Scala’s documentation many things, but above average is certainly not one of them. The lack of interest in trying to improve Scala’s documentation was the breaking point that made me leave.

                all we will see from now on is a language decreasing in popularity and momentum

                Yes, that’s my take too. If there is one thing consistent about Scala, it is that the people in charge simply can’t be bothered to deal with the problems people actually have instead of working on issues they would like people to have.

              2. 5

                It’s a great language to have learned, Martin Odersky is a master programming language implementer. Scala totally changed the way I think about programming, what the fundamental units of the language and runtime look like, and made something like Rust a lot easier to understand as well. Although F# is basically the same category of language. I’d definitely read a book on one or the other on top of any ML experience, this class of staticly typed FP/OO language has come a long way.

                1. 4

                  It’s amazing that so many people identify with this impression.

                  Like the rest, that’s the impression I got. I was a young functional programmer wanting to see what functional coolness was next, so I went to a presentation at conference where the code was to be in Scala.

                  Oh my god. It was painful to look at. There was a ton of IDE and code “noise” everywhere, and the presenter had a bit of a problem explaining why his solution looked the way it did in Scala.

                  That was enough for me, so I put that in my “no go” list. I don’t wish to trash anybody or their language, but what’s weird for me is that I haven’t met any coders yet exposed to it that didn’t have a somewhat similar opinion. It looked like Java and the compiler had a three-way with a Klingon, and this was the child.

                  It continues to impress me how much of coding is the experience and not the guts. In this way, it’s much like eating at a fine restaurant. You’re not excited about the food, you’re excited about the game, the experience, the stories, etc.

                  ADD: Just for the record, the point here isn’t that Scala sucks. It’s that people make these first impressions about various tools based on all kinds of things that might be silly. And then they never give them a second chance. The point is that the “furniture” and experience of a programming project and demo for some reason mean more than what’s actually going on. I have no idea what that guy was talking about, but I remember my impression of the tool quite vividly.

                  1. 4

                    As someone that used Scala (and Spark) for a school project, I wasn’t terribly impressed either. Granted, I don’t think I’ll ever choose JVM languages without prevailing factors being in play (such as needing to target Android), and Scala wasn’t bad, but my experience with it didn’t make me want to use it more.

                2. 20

                  I don’t get Dark at all. It’s like let’s take all the vendor lock-in problems with serverless and make it 10 times worse with a proprietary language.

                  1. 5

                    The proprietary bit kept me away, but the developer experience looked incredible. Previewing code changes against recent traffic? Staged rollout of new/old code versions with automatic rollback when errors are introduced? I was tempted.

                    1. 2

                      i guess it’s if you’re already committing to serverless and accepting the resultant vendor lock in, it makes things even more convenient for you.

                      1. 1

                        This also confuses me: https://blog.darklang.com/fizzboom-benchmark/

                        There’s all this chatter about trying out different programming languages and performance and async runtimes and, like, the best benchmark they have gets less than 10 req/s on the “talk to a slow webserver” microbenchmark? Like, what? That’s not an impressive number.

                      2. 11

                        Seems entirely fair: author doesn’t need the low-level control and performance that Rust offers, and prefers ease and flexibility that comes from having a GC in the language.

                        1. 14

                          I think Rust is a wonderful community, ecosystem, and tooling, wrapping a language that nicely solves a problem very few of us have.

                          This is my feeling exactly. I think it is head and shoulders above the alternatives in the space it’s in, but I have never needed to work in that space, because for the problems I work on, the downsides of GC tends to be irrelevant.

                          I am very glad it exists, because it prevents more new code from being written in C and C++. I just don’t have a use for it myself.

                          1. 2

                            And not just GC per se. I have written very little code in the last decade that would have benefitted from Rust’s ownership model (which to me is the language’s killer feature) so there would be no payoff from the added cognitive overhead.

                            I’ve worked on low-level code bases earlier in my career that would have been great fits for Rust had it existed (lots of parallelism and mutable shared state that needed careful lock management and disciplined adherence to order-of-operations rules) so I’m well aware of the pain points it addresses, but it appears to bring very little of use to the table for a lot of software.

                            The right tool for the job!

                            1. 8

                              And not just GC per se. I have written very little code in the last decade that would have benefitted from Rust’s ownership model (which to me is the language’s killer feature) so there would be no payoff from the added cognitive overhead.

                              Hm, interesting, because I see that very differently: I write a lot of code where “handing from one component to another” is a fundamental operation that Rust makes strict. Think “write this to a channel/database/etc., invalidating usage on my side”.

                              I could live without borrowed references and with pervasive and more ergonomic smart pointers much more.

                              1. 6

                                I suspect this is a matter of personal taste. I’m working on a high level project now and I’m not finding Rust’s ownership any more hassle now that I’m comfortable with the language, and web applications ported from Go became less code + easier to work with.

                                It was however a real pain learning how to use Rust because of ownership.

                                1. 1

                                  And not just GC per se. I have written very little code in the last decade that would have benefitted from Rust’s ownership model (which to me is the language’s killer feature)

                                  Interesting; having not used Rust, I assumed that the ownership model existed primarily in order to support avoiding GC. Is there more to it than that? I guess it can also solve data race conditions when sharing mutable data across threads? (another problem I don’t have, because I never write concurrent code without immutable data structures!)

                                  1. 3

                                    Single ownership gives you automatic and deterministic resource cleanup as a side effect. You don’t need to remember to write defer f.close() or be limited to a single scope with f.open().

                                    Another benefit is that you don’t have shared mutable state, but you don’t have to go all the way to purely immutable. Exclusive owners can mutate their data without causing side effects. This helps understanding what is going on in a program: if I pass an object to a function is it going to keep a copy or reference the original? Can I mutate that object afterwards? Always clear with ownership.

                                    1. 3

                                      Sure but there are other languages where you do not need to remember these things either or have shared mutable state. I think F# is a sweet spot because I can do ~90% immutable ~10% mutable code and it just works extremely well. The 10% mutability happens in a short context and I never give out mutable references. Having to deal with mutability or disposable things in a small amount of your code is doable and I do not need to fight with the compiler to get basic code to work (as opposed to Rust).

                                      I pass an object to a function is it going to keep a copy or reference the original? Can I mutate that object afterwards?

                                      These are sort of questions we do not need to ask with F# either.

                                    2. 1

                                      Rust used to have a GC, in its early days (@T), so it can’t be just that. I don’t know if there is an official answer to “why rust”. There is a section in the old FAQ about the garbage collector that tells a bit more about the other benefits of tracking ownership: https://prev.rust-lang.org/en-US/faq.html#is-rust-garbage-collected (got to scroll up a bit because the “try the new site” banner hides the start of the section).

                                      Apart from the matter of concurrency, there’s also non-memory resources (like file handles), which get tracked like memory.

                              2. 5

                                pattern matching doesn’t work all that well

                                Anybody know what the author means by this? I haven’t used Rust a whole lot but pattern matching seemed fine to me, other than having to add a few &s here and there to satisfy the compiler.

                                1. 16

                                  In Rust, you can’t pattern match through Box<T> or Vec<T>. But you often need those indirection to implement recursive data types.

                                  That means that, practically, you are restricted to one-layer pattern matching for recursive types, and have to split deep matches into a series of nested shallow matches.

                                  1. 5

                                    There is a nightly feature (box_patterns) that lets you match on boxes.

                                    1. 6

                                      Sadly, that isn’t generalizable, so marching on nested String, Vec, etc. remains cumbersome.

                                      1. 1

                                        Could you not match on the slice? Or perhaps I’m misunderstanding

                                        1. 4

                                          Say if you match on a variant that contains a Vec, you can’t match on that directly - you have to pull it out, then call as_slice on it.

                                          1. 2

                                            Oh yes! My eyes skipped over the word “nested”. Thank you

                                          2. 2

                                            To Rust, Vec is just a regular struct {len, capacity, pointer}, so that’s what it’s pattern-matching on, not its elements.

                                            For values at the top level you can usually easily transform them like match vec.as_slice() {}, but if you want to match a nested value, there’s no room for that:

                                            match compound_value {
                                               Foo(Bar([first, ..])) => …

                                            Then in Foo(Bar(Vec)) Rust doesn’t know how to match on Vec‘s content. There’s no language feature to explain that [first, ..] should compile to first = vec.remove(0) or that it should perform vec.as_slice() before matching.

                                            1. 1

                                              I think match_default_bindings might do this.

                                              1. 2

                                                match_default_bindings (match ergonomics RFC) is for now only a syntax sugar that makes patterns forgiving about missing ref or &, but the actual behavior stays the same, with the same fundamental limitations.

                                                Specifically moving out of a Vec is far off, as it depends on DerefMove, which is at the stage of “hmm, maybe we should have something like that, but not sure how to pull that off”.

                                        2. 2

                                          I think they are now preferring match_default_bindings, but I could be wrong. This is definitely a pain for me as a language implementer. :(

                                      2. 7

                                        It’s discussed on the other post at https://blog.darklang.com/first-thoughts-on-rust-vs-ocaml/#pattern-matching.

                                        That section is just a summary of the last post, sorry for the confusion!

                                      3. 3

                                        Rust with oilpan-style gc would be fabulous but nobody is interested in building it, including me.

                                        1. 7

                                          You know that Rust used to have a GC? ;)

                                          Can you give me a quick intro of what makes a oilpan-style GC particularly suited together with Rusts ownership model? (Ownership of GC handles is an interesting property, btw.)

                                          I know at least one person who would be interested:

                                          https://without.boats/blog/notes-on-a-smaller-rust/ https://without.boats/blog/revisiting-a-smaller-rust/

                                          1. 2

                                            Using such a Language would probably be interesting for many people. Yeah I preach “no GC” but tbh for writing one-off tools it’d be nice to have all of the features of rust, excluding the memory management overhead.

                                            1. 1

                                              Sounds like Swift.

                                            1. 1

                                              Would D not be close to this?

                                              1. 6

                                                D doesn’t have first-class algebraic types; std.variant is quite limited in comparison to other languages.

                                                1. 2

                                                  This implementation is somewhat better, though still not great.