Ask HN: Why are all of the best back end web frameworks dynamically typed?
Ruby on Rails, Django, Node JS all have great developer experience, are highly configurable but easy to use and hit the ground running.
Spring, Gin, anything Rust, .Net, etc all are very difficult to configure properly for even the most simple SaaS products.
Why is that? Are there any good statically typed web frameworks?
34 comments
[ 1.3 ms ] story [ 109 ms ] threadI mean sure you can specify that this var is a int32, but pretty much every tutorial, every code snippet out there, will do.
And just let Go guess what the type should be. So yeah, Go CAN be statically typed, but in practice it rarely is.But regardless of that, are you also implying that Gin is as good as nodejs/Django/ror? There are lots of bad dynamically typed web frameworks, but I'm looking for a good one that's statically typed.
I disagree but my position is purely preference/subjective. The main point for me is that static types make reading other teammates code much easier. If I could use statically typed python/Django, that would be amazing.
Modern Python with things like https://learnpython.com/blog/python-match-case-statement/ + mypy + Ruff for linting https://github.com/astral-sh/ruff can get pretty good results.
I found typed dataclasses (https://docs.python.org/3/library/dataclasses.html) in python using mypy to give me really high confidence when building data representations.
And there's https://pypi.org/project/django-stubs/ for working with Django.
It really just doesn't feel as good or useful as using a statically typed language.
You can write clean Python without much fuss that is easy and simple to read.
I don't think the compiler with the error messages makes a difference when the business is pivoting between features, when they ask to add a new field to various forms, to generate new reports or add new emails in various points of the work flow. Or change the emails from one point to another point. Or add password less. Or just switch the external provider of an API from an important flow because there is a better deal elsewhere.
I am not saying static typing does not provide speed or flexibility, but I just wanted to say that business-relevant change has more to do with features than code.
I cannot comprehend this. It's like saying "Health has more to do with organs than cells." Organs comprise features. Features comprise code. To change the feature, one must change the code.
If the code is not business-relevant, delete it. It's a liability. We are not artists.
If the code is well-written, the compiler errors will echo the business' failings.
In practice, it essentially leads to one of 2 things
1. Any time you have to make a change for a prototype, you have to go change a whole bunch of dependencies on your library, even if the change is not used in those explicitly, all because of the prototype.
2. You start introducing dependency hell or duplicate code, to either abstract stuff away so you don't have to do the prototype changes, or you start writing duplicate classes/functions to handle different parameters.
Neither of which is either fast or flexible. Anyone who has worked at Amazon dealing with Java services can attest to this.
Dynamic typing on the other hand is actually flexible and fast. For example in Python when building out something that is changing quite often, its very easy to pass around dict objects.
And yes, dynamic typing, it can lead to more errors, but in practice, most all of these are caught during testing, and are just as straightforward to fix as compiler errors. If you try to access a dict field that is not in the passed dict, its pretty much equivalent to a compiler error.
> dynamic typing, it can lead to more errors, but in practice, most all of these are caught during testing
I think we're practicing such different styles of software design that one another's tools are a hindrance. For example, I don't think that "bugs are caught during testing" because I am testing first. Unless you mean user acceptance testing, which is uncomfortably late in the cycle.
When running a dynamic type language, these errors are going to be caught at runtime.
What Im saying is that from the perspective of code execution, there is no difference between the two as long as those checks are performed somewhere before you ship your code, whether in tests or in the act of compilation.
Preferably, they're performed before I push to a remote repository. Hopefully they're performed before I alt-tab away from the editor for a single second. Hopefully they're performed before I fuzzy-find a collaborator module to edit.
> When running a dynamic type language, these errors are going to be caught at runtime.
Only if those code paths are exercised in a test suite, or am I doing it the hard way?
Spring boot sure, Spring boot works out of the box by slashing all of the configuration from spring, "convention over configuration" they say, which does not help understanding the underlying magic that Spring does, it just adds more magic upon it, so it's just yet another layer of abstraction to learn. Is that all? No! We need more annotations, so add Lombok on top of the existing @ hell.
.NET MVC is a very good framework, but I know the devops can be weird and a pain.
Overall, most frameworks get in the way anyways, IMO. I prefer to cobble together several modules that each do one thing well. E.g. use FastAPI for the endpoints, and any unrelated ORM you like for DB stuff, etc.
I suspect that if I really sat down and tried to more thoroughly write my thoughts on the subject, a lot the things that annoy me with it may just apply to dynamically typed languages in general (and sometimes just Python in general).
I don’t think the dynamically typed ones are better, just better known.
The website has lots of information and videos and beginner tutorials.
https://ihp.digitallyinduced.com/
They've both improved and the industry has matured.
https://ihp.digitallyinduced.com/
despite not remembering much haskell!
This assumes you can get past nix for the install.
I find IHP well-designed. I just wish the licensing scheme were more transparent.