Rewriting a lot of things was time well spent rather than trying to tame the dynamic nature of Python and my tendency to overuse it.
And I can't believe I'm writing this after all these years evangelizing Python and dynamically typed languages.
Rewriting a lot of things was time well spent rather than trying to tame the dynamic nature of Python and my tendency to overuse it.
And I can't believe I'm writing this after all these years evangelizing Python and dynamically typed languages.
I've been fighting battles in Python backend services to get a nicely decoupled API, logic and DB layers for a while...but sqlalchelmy, alembic and flask/django/fastAPI are my safety blankets
I’ve done a lot of C# and Java now over the last few years, and I don’t love their type system, esp compared to typescript, but they scale much better against large codebases - especially with tooling like bazel.
I’ve been looking at Haskell and Rust a lot to fill this intermediary: code that’s performant, with a very expressive type system.
I maintain(ed) a number of popular python packages, and that journey lasted for nearly a decade.
I ended up being very happy with F# as a middle ground for several years, but eventually migrated back to C# as they started adding more and more F# features. The primary challenge with F# was the parity mismatch with the underlying runtime, so you end up having to write a fair amount of non-idiomatic F# to interop with common libraries. But otherwise it's great. (I also tried Scala for a year and hated it: too many ways to do any one thing).
As for the reasons:
- Static typing and C# projects makes code organization and refactoring dead easy.
- Modern C# doesn’t require that much boilerplate, and has features that allows a developer to speed up development, like Python.
- EF Core covers everything I need from SqlAlchemy/Alembic.
- LINQ is an awesome way to work with collections. Type safe DB queries comes handy both when developing and refactoring.
- ASP.NET covers everything I need from flask/Fastapi.
- More speed and lower resource usage is nice.
- Being able to use an IDE with it’s full power is nice.
My main reason to switch was static typing, and my only requirement was a good ORM comparable to SqlAlchemy. The rest is just bonus.
> - Being able to use an IDE with it’s full power is nice.
In my experience, Visual Studio is much slower when developing. My Python workflow affords a 200ms red-green-refactor loop, while VS is on the order of several seconds.
This might not seem like much, but it has a great impact on my engagement, flow, and satisfaction.
It’s worth it in the end. YMMV.
It costs money, but I've paid for NCrunch for a fair few years and find it invaluable for this reason. It doesn't even need you to save changes before it spots them and runs affected tests in the background.
If cost is an issue you can also start `dotnet watch test` going in a terminal/command prompt for non-interactive live-reload testing.
Maybe if you're building a large high-performance server, you should invest in performance. But otherwise, if you only look at at computational complexity, and batch up/avoid I/O when possible, you're fine.
What follows is my opinion, I am aware it is my opinion, but in my sphere of influence, it is not up for debate when it comes to writing code. It might occasionally be a conversation over lunch.
I put python in the same bucket as BASIC. It's not a production language. "developer time is much more valuable than machine time." Yes. Absolutely. Iteration speed is vital. But it is vital in more than just the test loop. It is important in the "minor refactoring of various classes" up to the "major refactoring of entire systems" loop too. And python just doesn't make that easy. It actively makes it difficult. It makes comprehension difficult. It's difficult to look at python code in a code-review and have a good idea of what the classes involved are. I don't even write scripts in it any more. I've found that any script that is worth writing is likely to grow and evolve over time, and if it is not written in something like C# or Java, then it will become an intolerable mess. I've seen entire organizations that are basically cargo culting.
I encourage you to learn a statically typed language and its tooling.
The upside is hopefully you "don't need to run it as many times" but ... eh. No thanks.
Another reason is that decoupling and adding layers to your code is more part of the culture. Look up “domain driven design C#” or “onion architecture C#” and there will be a lot of resources on how to achieve it. There is stuff out there for Python as well (and the concepts translate between languages), but not nearly as much.
It feels a lot more professional than other ecosystems. For example, they actually talk about layering/coupling as professionals should! People actually seem to talk about architecture as well rather than blindly believing that the conventions forced on them by a framework are sufficient for all use cases.
I especially like the gradient in the .NET world from micro ORMs to full-fledged ORMS. Most ecosystems seem to develop a big ORM that constantly accrues features (and bugs) and eventually becomes enshrined as a "best practice" because it acts as a kitchen sink.
The amount of open source in dotnet is great. (I think more than Java? My impression of that is dominated by Apache etc., though my experience in the Java ecosystem is limited. Presumably people in Java land would expect the same of dotnet being dominated by Microsoft, but that's really not the case).