Also, thanks for sharing your story. Elixir is a great language and I love seeing it being adopted more and more everyday.
Also, thanks for sharing your story. Elixir is a great language and I love seeing it being adopted more and more everyday.
* Haskell influence on the language, especially early on, encouraged the omission of dots and parentheses wherever possible. Just about every piece of sample code was written as an undifferentiated stream of tokens. There is a mental burden.
* Haskell influence on the community encourages category theory solutions to all problems. This harms interop with Java libraries, in addition to requiring a number of concepts that are safely ignored in many/most other languages.
* Scala's rich OO system (classes, interfaces, traits, singletons, case classes, implicits, etc) results in frequent design paralysis, not to mention taking a while to learn.
Elixir suffers from none of these problems, while retaining some of the things that made Scala a pleasure to use, notably the actor system of concurrency and the use of immutable data structures.
> Haskell influence on the language, especially early on, encouraged the omission of dots and parentheses wherever possible.
This is considered an anti-pattern in the Scala community. The last library that used this at large scala was sbt, Scala's build tool, and now everyone discourages the use of infix operators.
> Haskell influence on the community encourages category theory solutions to all problems.
This is simply not true. First, there is no Haskell influence on the language. Scala is a functional programming language, all similarities between the two are just fundamental to how their type systems work and the foundations of the paradigm. Second, I contest heavily that the Community encourages category theory to solve all the problems. There are many subcommunities in Scala and many styles, but if you talked to some Scala developers nobody would agree that category theory should be applied to all code. In fact, most people don't. They just use Scala because it's a better Java that boosts their productivity.
> Scala's rich OO system (classes, interfaces, traits, singletons, case classes, implicits, etc) results in frequent design paralysis, not to mention taking a while to learn.
Absolutely agree that for someone not experienced, it may be difficult to know what's the best way to design libraries (this is more of a problem with libraries than applications). This is a big problem of Scala that I think we're solving by making the language more opinionated and being more open about what's encouraged and discouraged.
If you ask for my opinion, I think we also need to make a better job at communicating all this knowledge that advanced Scala developers learn but that is usually kept to closed circles.
Since Scala has no build-in way to define FP constructs(monads, functors.. ), cats and scalaz are practically inseparable from the language itself when you try to go beyond the basics in FP. So, it is very easy to see where all the confusion is coming from
I spent three years on the 2nd largest Scala 'team' in the U.S (first as an engineer, then leading a sub team), the problem is that using Scala as a 'better java' doesn't really buy you much productivity wise. A small percentage of sub teams tried using Scala this way and hit a lot of road blocks with the unfamiliar syntax, immature tooling, and other quirks.
The teams that had huge productivity gains were the ones who leaned heavily on the functional features WHILE caring about overall readability. That means yes, we used Scalaz but we discouraged the omission of dots and parentheses (as you mentioned), discouraged operator overloading/symbolic methods, and were very deliberate about when to reach for features such as HKTs or some of the more unfamiliar features of Scalaz.
Overall it lead to a very productive and fun development experience, and at the same time illuminated many ways in which the Scala ecosystem could also be improved.
2. I mentored a couple novice developers working on a Play codebase, the rough guideline was to use libraries that depend on Scalaz, Cats, Shapeless ... but never import any of them in our codebase. No HKT in our code either. (Nowadays I work with all that on a daily basis, you can keep things reasonable).
3. I think you're mixing up a few unrelated things. Scala's OO model is cleaner than Java's. Implicits abuse is avoidable with frameworks like Play.
Things can get rough when you take FP or OOP to their logical ends, the sweet spot lies somewhere in between.
There are other syntax quirks as well. A very very very opinionated take on Elixir syntax: https://medium.com/@dmitriid/in-which-i-complain-about-elixi... :)
(Note: I haven't touched Elixir in a while, so some of the things there may be wrong)
Optional parentheses were one of my main issues with Elixir, but once I understood why this choice was made, and what with the formatter judiciously adding them back in, I'm much happier.
(I recall having tons of issues when using the pipe operator + leaving out parentheses. Happy that these aren't much of an issue anymore.)
You need to sort of put your foot down on using out there FP stuff like some parts of scalaz and turning your code into line noise. The non-FP parts are nice and useful though.
I can go on for days on how someone wrote some unreadable Scalaz that had atrocious performance (even with @tailrec) and someone rewrites it in plain Scala for a 100x perf win.
Still.. would I use scala again? Yes, but mainly because it allows you to use high quality Java libraries that are unmatched by any other language. It’s also just much nicer than Kotlin.
We also really like Akka...
I think it has to do more with the latter. To me, Scala is too powerful - it rivals C++ in complexity, despite being half it's age. It almost feels like every Scala codebase is written in a different language, and I always felt I spent more time parsing Scala than understanding the code. It's a powerful language to write, but hard to read - almost the complete polar opposite of Go. As a result it can be very hard to bring new engineers up to scala, and even engineers that know Scala have to learn "your flavor" of Scala.
Elixir is a dynamically typed language, so all types in Elixir are inferred by the runtime.
1 + "some string" + [A,List,Of,Somethings]
Compared to javascript where: 1 + "2" == "12"
Statically typed means that variables and functions hold or return specific types which can be determined before execution.Sometimes useful, but the type system ends up offering few meaningful protections as a consequence.
However, C does allow you to write code that can not proven to be legal with respect to the formal system of the language and get it to compile, I think that is what you are referring to.
But just because you can write an invalid program does not mean the type system doesn't exist or is flawed. I can also write an invalid Haskell program.
The difference between these two would be that the haskell program can be proven to contain only operations that map to well-defined operations in the formal language model by an automated process, while the same can not be done for C in the general case.
However, just because you can not always prove conformance to a formal model using automated means, doesn't mean that no formal model exists (because it does!).
If it were type coercion, we would expect the add function to have either of these two behaviours:
- coerce the input arguments to strings, i.e. implicitly accept two strings and return another string
- coerce the input arguments to integers, i.e. implicitly accept two integers and return an integer
However, that is not what is happening here.Of course, in Javascript it is implemented as a function that takes the theoretical "Any" type and decides what do do at runtime. But in a statically type language, the equivalent mechanism would be dynamic/multiple dispatch (or a static overload, possibly in combination with a generic/template method) -- not type coercion.
The "+" (operator) case is only special in languages that do not implement operator overloading -- it is completely orthogonal to the type system.
I don't think anybody ever did. The definition of "strong" and "weak" seem to be entirely subjective; and of course everybody considers their favourite language to be "strongly typed". It's like a reverse no-true-scotsman.
I have to say though, coming from a C++ background, Scala still feels much more beautiful, clean, and safe than C++... but then, almost everything does ;)
It's also interesting that he wants the ability to "run your tests for the intermediate refactoring steps that wouldn’t typecheck and then let you fix up things later."-- I'm not sure what it means to want to run code with ambiguous types in a type aware language like Scala. Type information is deeply involved in runtime program behavior. (E.g pattern matching on types, resolving typeclass instances)
I certainly agree that nontrivial sbt work is rough.