From ES6 to Scala: Basics
scala-js.org
scala-js.org
ES6 wins, 'val' and 'var' are annoying close to each other.
Primitive Types
Scala hands down. Not even close.
Functions
Scala is more expressive (well if you ignore the types). I wish more languages would do the Haskell thing and let you write the type sig at the top. Typescript functions get so long.
Anonymous Functions
Very similar, so calling it a tie.
Default, named and rest parameters
I'll give this one to ES6 because the spread syntax feels more intuitive than * at the end of a type.
if, while, for, match control structures
Scala, because if is an expression and the for loop syntax is so concise. Also forget how nice nested looping was.
Classes
Scala. It's just more concise, I always liked not having to write boilerplate constructors.
Case classes
I mean I guess Scala but I still prefer polymorphism to pattern matching (please don't hurt me 2022 programmers)
Objects
Scala is shorter and more expressive here.
Traits
Scala because I never liked mutating objects, though I guess that's the prototype way.
Option, the type safe undefined
I mean Scala because I guess it actually has it, but worth pointing out it's like 30 LOC to define one for JS, depending on how many convenience methods you want.
----
Pointless post but this has made me kind of nostalgic for Scala. Maybe I own a computer fast enough to compile it now..
Disagree. I don't like either Scala nor ES - but "const" is really confusing. It implies that whatever we store is constant, but it's not. I can store a mutable object and it changes whenever I want - only the reference is constant.
> Default, named and rest parameters > I'll give this one to ES6 because the spread syntax feels more intuitive than * at the end of a type.
Not sure. If I imagine I come from a language without such a feature, then having "..." infront of the parameter seems confusing. "...args..." would be clearer. Having "Double*" is also a bit confusing, but I find that * is often used for such a situation (e.g. in regex)
> Case classes > I mean I guess Scala but I still prefer polymorphism to pattern matching (please don't hurt me 2022 programmers)
Scala is really lacking a way to easily support structural typing like typescript does. ES clearly wins here, since in Scala you have to define the case class in advance. And while you can just use maps, you give up typesafety.
That's the meaning of const in C++, C and a few more languages. In most other language, it just means that the reference stored in the cell corresponding to the variable is a const, just as you say. I don't think that's too bad, except when switching languages too often.
> Scala is really lacking a way to easily support structural typing like typescript does. ES clearly wins here, since in Scala you have to define the case class in advance. And while you can just use maps, you give up typesafety.
Scala has great support for structural typing. (One of it's main advantages IMHO), e.g.:
def callSpeak[A <: { def speak(): Unit }](obj: A) {
// code here ...
obj.speak()
}Haha, I see - it's been a long time since I used C/C++. But n terms of general understanding and in the context of languages becoming more functional I still think that const is not a great choice. But you have a good point.
> Scala has great support for structural typing. (One of it's main advantages IMHO), e.g.:
I would not call this great support. If the support were really so good, there would be no or much less need for things like shapeless and chimney.
In your example you make it so that you can pass any object that has a speak method and yeah, that works. But change the type of speak to Integer, add another one for string and then create (not pass!) a simple data-holding object that you can pass to it, without defining a case class first. Then the syntax is not so nice. And composition for these kind of things becomes tricky quickly.
Looking at it the other way, Typescript is really lacking nominal typing and the safety and simplicity that it provides. Structural typing isn't needed if you don't care about Javascript / dynamically typed coding patterns. But Typescript is optimized for exactly that, that's why it has structural typing. Personally I much prefer Scala's type system, it is very rare that I long for more dynamism than it affords, even though I've coded in and liked Javascript for years prior to that.
True.
> Structural typing isn't needed if you don't care about Javascript / dynamically typed coding patterns.
I think this idea of yours is limited to what you do with Scala. Ofc, in Javascript you don't need it, because types don't restrict you. But do datascience or dataengineering and it becomes painful quickly - look at spark frameless for example. It needs a lot of typelevel machinery to make it work. "easy" is different.
There are still a few things I miss though:
* Pattern matching and exhaustive checking. Using a switch statement it is possible to define a function that can emulate the compile-time exhaustive checking, but it's still rather weak compared to what you can do in Scala.
* Implicits. Being able to define something that can convert say a UUID to a String or vice versa automatically just feels like magic, especially when dealing with data from third party systems.
* Compiler macros and metaprogramming. It enables tools like Chimney (https://scalalandio.github.io/chimney/) to be built, which I don't think are possible with TypeScript right now.
This is by far the biggest problem of Scala. After Typesafe rebranding and dropping the ball as a main Scala supporting body, it all went downhill from there. Ehich is a shame as Scala is a solid language with very good features.
Here's one I wrote: https://github.com/sbernheim4/excoptional
I fully believe it to be the best Option implementation for JS/TS
The only thing that can be annoying is when you want to have a typesafe interface and have to write a lot of adapters for javascript libraries.
Fortunately there is even a project that can make use of typescript interfaces for those libraries, so that you can use them from ScalaJS more or less automatically: https://scalablytyped.org/
The biggest limiter that keeps people from replacing more local scope imperativity with expression style seems to me that very practical, almost depressingly mundane topic of debuger ergonomics. Stepping through and looking at intermediates just works, and it's so easy that the mind can remain focused on the domain problem. If there was some miracle UI paradigm that provided similar ease of understanding to deeply nested expressions we'd hardly see any local vals at all. But I doubt this miracle UI will ever happen, we do know that it hasn't happened in decades of trying to make excel expressions more approachable, with presumably millions of dollar thrown at the problem.
I think I'm done for today with provocative statements.
But it was a different local maximum a decade ago, when every language and its dog became OO. And perhaps a decade from now, it will be another.
I haven't looked into the options but I would love to see something that feels like it was meant for the language from the ground up. Eg. Blazor probably qualifies because it was written specifically for C#
The downside of this approach is the ecosystem isn't that big compared to JS.
This comes at a cost of unsafety / unsoundness which is a tradeoff by design. Scala's type system is infinitely more robust. I use Typescript occasionally with all the strictest flags, and yet it allows invalid code that shouldn't compile, all the damn time. Such unreliable type checking is all but worthless to me personally.
Scala is hands down better than Typescript for functional programming. It was actually designed for that from the start. But it's not religious about it either, its OOP features are rich and integrate with FP features very nicely.
Scala.js community and ecosystem is small compared to Typescript, but very diverse and passionate. The mechanism of interfacing with JS is in principle similar to Typescript, but in practice takes a bit more setup.
Also with Scala/Scala.js, you get to a whole other level of productivity when you use the same language on both the client and the server.
I'm intimately familiar with both languages but thanks for the run down
I haven't had a chance to compare speeds apples-to-apples, but I expect Typescript incremental compilation to be faster than Scala.js. Though, to me this metric has stopped being relevant because using a type safe language I stopped looking at my changes in the browser every minute, like I used to do when I was writing frontends in Javascript.
LESS/CSS compilation is the only part where I really care about speed since pixel pushing always needs trial and error, so I set it up to be separate from Scala.js compilation, and it's as fast as it would be in JS world.
nitpicking but CSharp rarely requires type definition, AFAIR it's about the same as Scala
We recently switched from Haskell to Scala for a new project due to the scope of the JVM ecosystem, in spite of having inline-java available in Haskell and GHC‘s excellent FFI.
We’re a team of mathematicians and physicists working in finance (not a fintech company though). Originally we chose Haskell because it felt as the most natural fit to us to expressing our domain models and producing great EDSLs. But now it looks like we‘re going to transfer all prospective projects to Scala.
It took some time to get used to it. At first the syntax felt unergonomic with Scala 2.13. Scala 3 / Dotty seems to have improved over it significantly. And the functional programming libraries come to the rescue.
Scala’s standard build system, the sbt, is a boon, we got to really like it.
Then the differences in the semantics occupied me for a while, but I managed to quickly get used to them. Except perhaps for the local type inference. However, with certain GHC extensions, the program becomes undecidable anyway, and we have to specify the types here and there despite the global HM style inference. Overall it still feels like I can more easily express type-level programs in Haskell rather than in Scala. GHC Haskell feels just more expressive and powerful. But this is likely to mostly be due to me having written Haskell for several years now.
However, me and my folks all have become significantly more productive in Scala 2.13, and even more so with Scala 3, than we were used to with Haskell. You can do the easy things the easy way.
it’s awesome that in Scala you get the benefits of both worlds, and can commit to explicitly managing effects when you’re ready, laying ground for quick prototyping and cost-efficient MVPs. You simply get the opportunity to run more experiments in your business area rather than in the programming language theory.
With ScalaCheck there’s a QuickCheck for Scala, there’s also a couple more for the JVM. ScalaTest is more than good enough. MUnit is also nice. Due to the different type system, we had to extend our testing. There are also great integration and end-to-end testing frameworks for Scala and the JVM. So we’ve mostly covered our implementation risks. I’m unaware of anything for which GHC would provide stronger guarantees for our services.
We run and maintain several services written and executed on another managed and unmanaged platforms. We benchmarked some of their aspects with almost identical implementations in Scala, trying to translate certain idioms to a more natural Scala style. Well, we were surprised to see how extraordinarily well our Scala services performed, we even outpaced a highly optimized Go service, but we couldn’t match a modern and optimized C++ service whose implementations only few folks in my team understand, more or less.
In other words, we’re extremely satisfied with Scala 2.13 and 3.0 through 3.1. Binary compatibility is attained through cross-compilation with a couple caveats pertaining to certain old-style macros. So we’re mostly certain that we’re sticking now with Scala.
For front-end development, there‘s also GHCJS which transpiles Haskell to JS and PureScript along with Elm transpilers that are great for the front end, with Elm being extremely performant but sometimes quite painful. We went with some PureScript + React and were mostly satisfied. We haven’t dealt with front ends in Scala.js yet though.
I would be interested in the things from Haskell that you miss most and that you would like to have in Scala!