8 ms·
I used Scala and loved it for a period, back in the Scala Lift days. It’s a beautiful language in many ways, that is also just too bloated with complex features
by crystaln 6y ago
I used Scala and loved it for a period, back in the Scala Lift days. It’s a beautiful language in many ways, that is also just too bloated with complex features that enable a small amount of brevity at the expense of a huge amount of cognitive overhead.
I do kind of miss it though. Right now I’m pretty happy with Typescript...
- lihaoyi 6y agoThe community as a whole has definitely dialled back use of complex features. If you're used to Lift-era Scala, that was probably the high water mark in terms of "people having fun with confusing features and syntax", and things have gotten steadily more "normal" in the intervening half decade (perhaps approaching a full decade!) To be clear, these complex features are still there, it's just that people tend to not use/overuse/abuse them as much. Just like how Python has metaclasses and import-hook metaprogramming, but it's not something that a typical developer has to deal with on a day-to-day or even year-to-year basis
- cmollis 6y agolove your book.. and your blog. Thanks!!
- dwohnitmok 6y agoTo add to lihaoyi's sibling comment, some good examples of things people realized were overly complex pits of pain in Scala but were all the rage in the Lift days are the cake pattern and gratuitous use of implicit conversions. Those thankfully have largely disappeared. The design space of programs in Scala is still large (detractors might say too large), but it's way better explored now and there's a much clearer idea of the various tradeoffs among the various approaches as well as how to harmonize one with another.
- cutler 6y agoI think Scala will always suffer from its choice to make implicits so fundamental. Whether abused or not they impede compiler efficiency and complicate code. Implicits were the main reason I dropped Scala a few years ago.
- sideeffffect 6y ago> I think Scala will always suffer from its choice to make implicits so fundamental. Thankfully it won't. Scala 3 deconstructs implicits and discourages (or outright discards) the bad parts: http://dotty.epfl.ch/docs/reference/contextual/motivation.html http://dotty.epfl.ch/docs/reference/contextual/motivation.ht... "Implicits" are useful for the Type class pattern and is available in Scala 3 with an improved syntax. "Implicits" for implicit conversions is an ugly hack that should be avoided as much as possible and Scala 3 restricts it. "Implicits" for extension methods is a clever hack, and Scala 3 provides a dedicated syntax for defining extension methods.
- dwohnitmok 6y agoImplicit conversions I think are landmines that should to the greatest extent possible be avoided except in a few very select cases. Implicit arguments... man I go back and forth on that so much. On the one hand every crazy tower of abstraction that grinds the compiler to a halt in Scala inevitably begins with implicit arguments and you can have a really rough time with them if your IDE doesn't support looking up implicit arguments. On the other hand, if you want ad-hoc polymorphism, implicit arguments are really useful, often far more so than inheritance. My usual take on this is that you probably don't need ad-hoc polymorphism most of the time, which is my way of wriggling out of the dilemma.
- cutler 6y agoClojure has ad-hoc polymorphism and it isn't even statically typed so I don't get how implicits are so essential. Implicits are still alive and well in Scala 3 I hear so I guess they blew any chance of going mainstream (again).
- dwohnitmok 6y agoWe're talking about different notions of ad-hoc polymorphism (as you point out, static vs dynamic). For statically typed languages, implicit arguments (in some form or another) are really great at getting statically checked ad-hoc polymorphism. But even in dynamically typed languages such as Clojure, ad-hoc polymorphism mechanisms bottom out at some form of implicitness at runtime. I assume you're referring to multimethods here (which generalize protocols, whose very existence is a performance hack akin to atoms vs volatile, so I'll focus just on multimethods)? The entire lookup system based off of defmulti is really just the same thing as Scala's implicit system just at runtime rather than compile time, but even harder to understand IMO because it can change wildly at runtime. The same "spooky action at a distance" problems can result here. The reason this isn't an issue in Clojure is that multimethods are very rarely used and instead a lot of code just specializes on vectors or maps (again going back to my point that you usually don't need ad-hoc polymorphism).
- killtimeatwork 6y agoRe: implicits - just try doing anything in cats. The whole thing is hugely based on implicits, which you need to import with magical import invocations (which of course the compiler has no way of suggesting to you).
- sideeffffect 6y ago> the compiler has no way of suggesting to you Of course it does. And since Scala 3, it does suggest to you the imports you need for implicits. And IntelliJ does recommend imports even for Scala 2. Regarding cats, the codebase has been restructured, so that you won't need the implicit imports (or not as much at least): https://meta.plasm.us/posts/2019/09/30/implicit-scope-and-cats/ https://meta.plasm.us/posts/2019/09/30/implicit-scope-and-ca... The trick there is that the Type class instances were moved to appropriate companion objects which are searched by the compiler by default and thus the used doesn't need to do any manual imports.
- hocuspocus 6y agoHere you go: `import cats.implicits._` Done. And once you start understanding the typeclass hierarchy a little bit, finding the specific syntax and instances comes pretty naturally.
- vvillena 6y agoThinking of "implicits" as one single feature can be extremely confusing. OP is talking about "implicit conversions", which transform values from one type to another automatically just by being in scope. Cats imports bring in "implicit classes", which are a way to extend existing types with new methods, in a way that works even with parametric types in a type-safe way. That's the way to get ad-hoc polymorphism (aka typeclasses) in Scala.