Scala's features don't really overlap. Defining extension methods (with the new implicit class construct) is just syntactic sugar over implicit conversions.
Also, I find implicit parameters in general to be awesome. Because of implicit parameters, Scala achieves the best marriage available between OOP and FP. Scala doesn't just pretend to be FP. Scala is FP. Think of languages like Ocaml or F#, which have 2 type-systems in the same language.
Scala also doesn't side-step covariance/contravariance problems when dealing with generics, like other OOP languages do, providing the tools to deal with both. And we could agree that covariance/contravariance is a problem created by OOP subtyping, but if you've got OOP in the language, then you can't really pretend that all generic types are covariant or invariant and it's just awful to have two type systems in the same language.
> but ugly stuff that is there only for compatibility reasons can always be put into the standard library rather than the core language
That's what they are trying to do with SIP-18. Scala 2.10 emits warnings if you use implicit conversions without importing language.implicitConversions and they plan to transform those warnings into errors in future versions. Scala 2.11 went through a compiler refactoring phase, badly needed as the compiler's internals are messy, the plan being to make it more modular. Things are progressing in the right direction ... if only they got rid of the implicit conversions defined in Predef (and thus imported implicitly everywhere).
> Scala's features don't really overlap. Defining extension methods (with the new implicit class construct) is just syntactic sugar over implicit conversions.
Point taken, for this particular case. But subtyping and implicits still cover a large part of each other's functionality, and the former is a subset of the latter when you take into account the Liskov substitution principle.
> Also, I find implicit parameters in general to be awesome.
It is certainly better than having no way to do general ad-hoc polymorphism, but...
> Because of implicit parameters, Scala achieves the best marriage available between OOP and FP. Scala doesn't just pretend to be FP. Scala is FP. Think of languages like Ocaml or F#, which have 2 type-systems in the same language.
... I beg to differ here. Scala is biased towards OOP: you can do Java-style programming with no inconvenience and awkwardness, but Haskell- or even ML-style programming requires imperfect encodings in Scala. How do I do the equivalent of a ML signature ascription? (That is, assigning a signature to a module that possibly hides some members and/or makes some types externally opaque. This requires structural subtyping for modules.) Why is type inference unavailable precisely when you would most need it?
On the other hand, OCaml is biased towards FP. I still dislike it for other reasons, though: functions being eqtypes makes no frigging sense; the syntax is heavily biased towards imperative programming, so I end up having to parenthesize a lot; applicative functors are leaky abstractions in an impure language. And, unlike, Haskell, which may be huge but is ultimately built on top of a small core, OCaml strikes me as intrinsically huge (just huge, though, not full of warts like Scala). I dislike F# even worse, because it ditches the ML module system. When I want to use a ML, I use Standard ML.
> Scala also doesn't side-step covariance/contravariance problems when dealing with generics, like other OOP languages do, providing the tools to deal with both. And we could agree that covariance/contravariance is a problem created by OOP subtyping, but if you've got OOP in the language, then you can't really pretend that all generic types are covariant or invariant and it's just awful to have two type systems in the same language.
I do appreciate that it provides tools for managing the mess, but I still prefer languages that do not create a mess.
On a second though: does it actually manage the mess, or does it just make it worse? When a language's object model makes C++'s look simple by comparison, that is a sign that there is something wrong going on.
> That's what they are trying to do with SIP-18. Scala 2.10 emits warnings if you use implicit conversions without importing language.implicitConversions and they plan to transform those warnings into errors in future versions.
The whole subtyping via inheritance is far more ugly than that, and that is not going away anytime soon.
> When a language's object model makes C++'s look simple by comparison, that is a sign that there is something wrong going on.
Yeah, and when you want to make it excessively clear to everyone involved that you have not the slightest clue what you are talking about, then bringing up C++ is absolutely the best way to go.
Also, I find implicit parameters in general to be awesome. Because of implicit parameters, Scala achieves the best marriage available between OOP and FP. Scala doesn't just pretend to be FP. Scala is FP. Think of languages like Ocaml or F#, which have 2 type-systems in the same language.
Scala also doesn't side-step covariance/contravariance problems when dealing with generics, like other OOP languages do, providing the tools to deal with both. And we could agree that covariance/contravariance is a problem created by OOP subtyping, but if you've got OOP in the language, then you can't really pretend that all generic types are covariant or invariant and it's just awful to have two type systems in the same language.
> but ugly stuff that is there only for compatibility reasons can always be put into the standard library rather than the core language
That's what they are trying to do with SIP-18. Scala 2.10 emits warnings if you use implicit conversions without importing language.implicitConversions and they plan to transform those warnings into errors in future versions. Scala 2.11 went through a compiler refactoring phase, badly needed as the compiler's internals are messy, the plan being to make it more modular. Things are progressing in the right direction ... if only they got rid of the implicit conversions defined in Predef (and thus imported implicitly everywhere).