I find it especially amusing you cite typescript and the node ecosystem as superior. I've never seen such an unreliable and constantly changing ecosystem with dozens of frameworks and libraries ever in recent history.
I find it especially amusing you cite typescript and the node ecosystem as superior. I've never seen such an unreliable and constantly changing ecosystem with dozens of frameworks and libraries ever in recent history.
And the whole library/build ecosystem works a lot better - partly the problem is harder for Python because many "python" libraries rely on native code (whereas JNI is relatively rare), but it seems there are still four or five different ways to build and package Python projects and to work at an organization with a large Python codebase you end up having to understand all of them. (Every few years I see a blog post on how the packaging problem is totally solved now, for real this time, but at this point I've stopped believing them).
Seriously? Maven was one of the things that made me run away screaming from the Java ecosystem.
Beyond that there's a working central repository where all the important libraries are (and it's one of the few ecosystems that actually enforces code signing of all published libraries), and also a free repository server that you can run on-premises (and that's a normal JVM app that runs like anything else in the ecosystem) and use for private publishing and/or to proxy remote repositories to make sure you will always be able to rebuild any previously successful build even if a remote repository goes down. The release plugin enforces good practices by default, e.g. you tag a release and rebuild from that release, ensuring you can always recreate any given release; you may build a -SNAPSHOT which depends on another -SNAPSHOT, which makes it lightweight to make a change to an upstream library and check that it has the right effect on your downstream application (and the first-class IDE integration dovetails very nicely with this), but releases are only allowed to depend on releases, which ensures they're reproducible and immutable. None of this should be hard, and I think other ecosystems are gradually getting it right, but Maven just seems to have managed to make all the right choices and avoid all the pitfalls. You don't hear as much about it as you do about, say, NPM, but I think that's at least partly because it rarely goes wrong, so a lot of the time it's invisible to developers.
That, along with its horrible XML markup abortion, was exactly what I hated about it. Any behavior that was even moderately unusual was a monumental pain to implement.
Build scripts by their very nature need to be turing complete because the need for customization isn't rare enough.
>Beyond that there's a working central repository where all the important libraries are
Python got this 17 years ago, a good 4 years before maven even existed.
It is not supposed to be Turing complete, for things that need that customization, as the GP stated, you use extensions.
For anyone who likes maven, checkout cargo in Rust. It got everything right, and made build extensions easier to integrate.
They really don't. The build process should be simple and the same for every project; any actual logic can go in first-class code, that's what it's for (whereas finding out that a file somehow wasn't built, or got substituted before being built, makes for an extremely unpleasant surprise when investigating an issue). I find Turing-complete build systems end up with an analogue of https://martinfowler.com/bliki/SnowflakeServer.html - the "snowflake build", where every module builds slightly differently.
1) Compile time. In a tight dev loop, you can run Unit tests in say 2 seconds in Python, vs 15, 30, 60, 90 seconds in Scala (depending on code base size)
2) Django. Play is ok, but for web stuff I think Django does a little better job.
3) Ease to find help. Finding someone to write scala is hard. Usually means hire a Java or a Haskell guy and train them. Way more people know Python.
4) Easier to metaprogram. Sometimes, metaprogramming is awesome. Don't do it nonstop, but sometimes it is amazing. Reflection and macros and all of that exists, but it gets seriously awful to deal with.
5) Code readability. I read scala fine, but it can still take a while to parse a file to know what is going on. Trying to think through crazy scalaz or something can hurt your head, even if you get it.
6) No SBT
Now this is not to say all is perfect, things I do miss from Scala:
1) When you really do need high performance, you can get there without dropping to C.
2) Compile time checks catch many many errors. Really sucks if you write something in prod and get a ValueException at runtime. Obviously this means you missed a test, but a scala codebase with say 25% test coverage will be generally less likely to have runtime erors than a Python codebase with even 75% coverage.
3) IDE support. Mypy is a work in progress, but click though stuff still works a little bit better in Scala. Scala is not Java good at this though due to implicit magic, so this is becoming more of a wash.
True, but 95%+ of the issues you'd catch with unit testing in Python you catch during compilation in Scala, and that can be an incremental compile rather than a full compile. So once you have a properly set up dev environment the feedback loop takes less than 2 seconds in practice, though the one-off setup to reach that point is a lot fiddlier than for Python.
> 2) Django. Play is ok, but for web stuff I think Django does a little better job.
Heh, I don't like either, I'm a huge fan of Wicket (the one time I had to use Django I wrapped it in a Wicket-like layer I called smoff, which I think might even still be out there). Django is too page/request-oriented for my liking, I think a component-oriented library leads to much better design when you're making actual UIs. For REST endpoints spray is the best thing I've ever used, in any language: having your route definition look more-or-less like a route definition but being regular code that you can refactor in all the regular ways is amazing, especially when you get to the point of wanting to use e.g. custom directives and you can just click through to the standard directives and they're just ordinary code that you can adapt the same way as any other code.
> 4) Easier to metaprogram. Sometimes, metaprogramming is awesome. Don't do it nonstop, but sometimes it is amazing. Reflection and macros and all of that exists, but it gets seriously awful to deal with.
I think if you can't do it with Shapeless it's probably not worth doing. The typeclass-derivation stuff is more boilerplate than it should be, but it does work well apart from that, and always leaves you with something more-or-less understandable. Whereas some of the Python metaclass tricks I've seen have just been completely crazy.
> 5) Code readability. I read scala fine, but it can still take a while to parse a file to know what is going on. Trying to think through crazy scalaz or something can hurt your head, even if you get it.
I think you have to remember to compare code that does the same amount, not code that's the same length. Like, sometimes there will be a 1-liner in Scala that I'll have to mentally expand out to 6 lines to understand - but in Python the same code would have been 6 lines in the first place. And I think there's a huge benefit to being able to see a whole class definition on a single page, so I'd rather have the "compressed" single-line version even if it takes slightly longer to read in isolation than the "expanded" six-line version.
> 6) No SBT
Agreed. Can't stand it, have no idea why it's popular. I just use maven.
Not sure I agree with either of those. Compiler catches different types of error compared to Unit tests. Lots of ways especially when dealing with external libs or APIs where compile can't catch anything.
> Django wicket etc
To each their own. I despise SPAs, and neither code them nor use them if I can help it. DRF is really good for rest endpoints though.
> Meta programming
meh, different levels of it. Look at using Django ORM for some queries, vs say Slick. Slick is a bit gross.
> 1 liner vs 6 liner
Meh. In practice, Python is very terse also. Java vs Scala is a big line of code difference. I have not found Scala vs Python is that different.
It can if those libraries/APIs are written to use types effectively. In the early days of Scala there weren't many native libraries that did so, but there's a pretty established native-to-Scala ecosystem these days.
> To each their own. I despise SPAs, and neither code them nor use them if I can help it.
Um, agreed, which is exactly why I love Wicket ? I think we must've misunderstood each other at some level.
> Meh. In practice, Python is very terse also. Java vs Scala is a big line of code difference. I have not found Scala vs Python is that different.
In a lot of code I agree, but I think the cases where you will see "crazy scalaz or something" are precisely those cases where those things save a fair few lines. If you can write it in a readable line of Python, that will usually translate directly into an equally readable line of Scala.
Only programming Scala for one year, and it has been so depressing that it is beginning to affect my mental health. Mostly around sbt -- inconsistent incremental compiler issues, having more than one sbt causes a lock file I can't avoid, and even if they succeed, I get corrupt class files, so down to the one... and then getting inconsistent coverage report results, running all of the tests all over again because the report is no longer accurate, sbt and scala compiler are so dog shit slow that I'm back to "making tea" and "making sandwich" time during the edit & test cycle. Waiting just two extra seconds can interrupt a flow, waiting 12 minutes and you've lost it entirely.
Having worked with 20 or so languages professionally, this is probably the least productive I've ever been in my career.
Scala seems mega-boss hard.. please tell me it gets better
Once you get used to working with the type system you'll need tests a lot less - the cycle becomes edit/save/look at IDE "problems" tab, and that catches the overwhelming majority of issues, so you only resort to running the tests every couple of hours. It takes a while to make the transition though.
(Their intersection of uses isn't total, of course; Python's still got Go handily beat for numpy-ish stuff and interactive use. See Julia for a possibly-superior post-90s competitor in those areas, though I've only played with it.)
This definitely should not be interpreted as a slight on Go, many people would very happily trade that lack of benefits to get that lack of drawbacks.
But that's not to say it doesn't include good stuff.
I'd say support for lightweight threading, CSP (channels), structural typing, fully embracing first-class functions (crippled python lambda, anyone?), and a build-system integrated into the language rather than left to 3rd-party-tools are all distinctly post-90s features, for a mainstream language.
Also, gofmt is a huge boon. The Go community focuses on ecosystem and ergonomic human factors of development feels distinctly post-90s-lanauge to me.
Also, the 90s saw an intense, misguided focus on "object-oriented-programming", which Go completely, mercifully ditches. In that sense, it's post-90s. :)
(Well, OK, maybe OO-style programming is good for UIs -- thinking of stuff like iOS/Cocoa apis and Unity.)