7 ms·
A lot of the "cons" in the technical section just sound like a large engineering organization making pragmatic decisions. I can't think of any company working a
by cageface 14y ago
A lot of the "cons" in the technical section just sound like a large engineering organization making pragmatic decisions. I can't think of any company working at that scale that's successfully integrated a non-trivial amount of functional or logic programming. As much as hackers might not like it, there are reasons that coding at that scale is almost always a matter of banging out a lot of imperative code in a boring language like Java.
And I'm definitely not the only one that appreciates Go precisely because it doesn't play the Scala game of integrating every single academic PL research feature of the last 20 years but instead tries to be as practical and simple as possible.
- dsrguru 14y agoHave you witnessed any problems resulting from Scala "integrating every single academic PL research feature of the last 20 years"? (I was under the impression that aside from the actor model of concurrency, Scala typically gets used just like Java but with cleaner code.)
- guelo 14y agoI think the signature of the map function is now the standard example of Scala being too smart for its own good. def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That
- DannoHung 14y agoYeah, this is really a consequence of Scala trying to do much shit for you automatically with the map function. See, it's not just a map function, but also an auto-conversion function from any generic sequence to any other generic sequence. What the hell does that mean? Okay, so basically, take your standard map function. Run it on the structure you're mapping over. Great, now you've got your updated structure! Now, you don't just want to return the same type of structure you just had, you also want it to be a different structure, but with those modified elements you had for its contents. Now build that new structure from the thing you just modified (Scala may actually optimize the traversal and construction of the new collection into one pass, although I am not positive). And there's your return value. It actually gets more complicated due to the Liskov principle and the way that Java handles type erasure, but thinking about that shit just makes me fuckin' tired. You want to know what the map type signature should look like if the Scala guys weren't going overboard on trying to make things seem outwardly simple? class Functor f where fmap :: (a -> b) -> f a -> f b
- zem 14y agoi've never used scala, but it seems to me that that signature is simply ensuring that the type of map is as flexible as possible, and that actual specializations will be inferred by the compiler without the user having to actually specify any part of that.
- michaelochurch 14y agoThat's correct.
- quatrevingts 14y agoIt does indeed require some explanation to understand why this signature was chosen over a "simpler" signature that might have provoked less mockery from the interwebs. But it's not really that difficult, and it results in a collections library that's better than C#, Haskell, or Python. And I don't know about you, but I use collections a lot.
- duaneb 14y agoSo, coming from haskell and java, that snippet looks like a nightmare. How is that better than `map :: (a -> b) -> a -> b`?
- quatrevingts 14y agoWell, if you're using Java, you don't have map in the JDK. You can use Guava (or write your own) to get Iterables.transform(). But then, anything you map turns into an Iterable. So often you have to iterate over the whole thing once again to get the data structure you actually need. You could write Collections.map(), Lists.map(), Sets.map(), etc, until you get tired. (Guava does not include these.) But at this point you're still way behind Scala. What about flatMap, filter, slice, drop, scan, etc? Every collection in Scala has a huge set of methods that work on it. But they're not implemented again and again, because the type system is powerful enough to prove that the generic code that works for Set can be used for List. In contrast, every Java program is full of innumerable primitive operations expressed again and again, so you have to keep reading the steps of every for loop to determine, "oh, this one is doing forall. This one is map" rather than simply reading "forall", "map". Which is why, thanks to the above complexity, Scala can be much more readable than Java. What about Haskell? The existing standard library is fairly weak on collections. There are not that many implementations, and there's no typeclass that quite captures the idea of a collection: you've got Foldable, Functor, Monad, and possibly some others, which all get slightly different aspects of it. Small typeclasses are nice in that they allow more instances, but often you need some functions that aren't there. There's no typeclass which captures the size() function, for instance. That's mostly a library design issue, which is more tractable than a language issue, but still pretty hard to fix. There's one additional cool feature of Scala collections which I haven't touched on yet: transformations can result in collections that are different from the original collection type, and the most specific collection that is compatible is used. What does that mean? Say I map a TreeSet from an ordered element type to an unordered type. The result type can no longer be stored in a TreeSet, so you get a more generic Set collection instead. I'm curious what it would take to implement this in Haskell.
- Drbble 14y agoNow look at the Java Generics FAQ.
- eropple 14y agoAs always: it depends. As a peripheral observer and user of Scala, I feel like it gets a lot of things right if you want to use it as a "better Java". But that doesn't mean it's particularly usable as a "better Java"; obviously reasonable people can disagree but personally I find it uncomfortable to write Scala code for too long. It feels like it leads to awkward structures (blocks within blocks within blocks, hard-to-follow but oh-so-functional transforms) and an odd sort of terseness that reminds me of Python (not a compliment, I find Python irritating to read even though I like a lot of the ways it does stuff). It's like there's so much stuff there that it encourages you to be way too clever. "Too clever" is a thing and a bad one; somebody (maybe even you) has to puzzle out your cleverness later. I do find cases where the language actually does cause problems, though. There appears to be three main groups involved with Scala: PL academics, "better Java" people, and "why isn't it Haskell?" people. The last group is, to me, rather frustrating, because it's the group that gets up in arms at the idea of a 'for' statement in the language. (The standard method of iteration is a foreach method over a collection and it is insanely slow; people resort to writing while loops because the foreach construct is so laughably slow. Why am I faking a for loop in such a "modern" language?) There are a few areas like this where practicality has apparently lost out to zealotry and it makes the language feel vaguely hostile to somebody who already Does The Right Thing in Java (immutable-by-default, dependency injection rather than creation, etc. etc.). As silly as it may sound, when I'm writing Scala I don't feel welcome in my own code--and I've been using Scala off and on for a couple of years, it's not just fear of the unknown. I'm actually really looking forward to Kotlin (and Ceylon, to a lesser extent) because it's a language with a focus. JetBrains knows where they want to go with it instead of just dumping a box of stuff on your lawn and telling you to piece together what might or might not actually be what you want. The comparison always reminds me of The Big Lebowski: "Say what you want about the tenets of National Socialism, dude, but at least it's an ethos!"
- jedws 14y ago> foreach is insanely slow no, in 2.9 using a 1 to 10 generator and a foreach was slower than using one using primitives due to the boxing. This is fixed in trunk. > gets up in arms at the idea of a 'for' statement in the language Scala's for is an expression, you can use it as a statement by not yielding anything if you want. Scala's for is extraordinarily versatile, basically allowing you to work within any monadic context (where a monadic context is some container that implements map/flatMap and some other optional methods. These "I can't believe its not Haskell" people tend to want to stay with the realm of FP, which is a very useful place to be. Minimising and tracking side-effects and having more expressive and useful types makes more composable software. This is not at all academic, it is an entirely practical result. It does however require you to rethink your approach to writing code, and it really helps to learn a few seemingly difficult things like the typeclassopedia (Monads, Monoids, Functors, Applicatives etc). Personally I find that the Scala community is generally consolidating around functional approaches, and that this is a very good thing. It is a step beyond a "better Java" and is perhaps more initially intimidating, but it is definitely worth the effort.
- tikhonj 14y agoFrom what I've heard, Go goes too far in the opposite direction and integrates basically no modern research.
- Jare 14y agoCharacterizing Go like that would be too harsh. It certainly does integrate more experience than research, which is why Go is almost as often explained in terms of what it doesn't do as for what it does.
- duaneb 14y agoGo is not a research language (e.g. Haskell), it is pragmatic. I suspect a part of the design decisions of Go factored in training for people using that language. At a certain point, features that are alien cost more in training costs than they will gain in "elegance" or whatever.
- luriel 14y agoI don't think the concern is training, but the complexity caused by how various features interact, and how hard they make to reason about code. Go is designed so it is very easy to read and reason about what code does.
- cageface 14y agoThat's what I like the most about it. All the context you need to understand a block of code is right there, but it's still less verbose than something like Java. We all acknowledge that we spend more time reading than writing code but for some reason we still design languages that make writing it the priority.
- tikhonj 14y agoI don't know. Maybe it's because I've been mostly looking at Haskell and OCaml recently, but most of the more "researchy" features and languages I've seen aim to be easier to reason about. Unlike most languages (including Go, I believe), researchy languages tend to have very well defined semantics based on well-understood math--really going out of the way to be easy to reason about!
- gatlin 14y agoWhen I squint at Go's syntax, underneath the C-like facade I see: * higher order, first class functions * lists (squint at the slice a bit; also chans) * maps * flexible structs (curiously, you attach "methods" to them much as you attach functions to Haskell typeclasses). If anything, driven by pure pragmatism for the sake of concurrency and distributed computing, Go actually does implement really awesome functional primitives. However, it's built to be familiar to C and doesn't talk about it much. Very, very clever.
- fpgeek 14y agoPersonally, I love the OP's response to your last comment: "I hate Scala with a passion, for what it's worth. I just wish there had been more advocacy for it." I wouldn't characterize myself as hating Scala, but I understand where he's coming from on both points. There are reasons that this static typing fan tends to prefer Clojure to Scala on the JVM. Also, it's just a beautiful quote.