5 ms·
Have you witnessed any problems resulting from Scala "integrating every single academic PL research feature of the last 20 years"? (I was under the impression
by dsrguru 14y ago
Have 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.