@sir I think Python is only good up to 1000 lines of code. Beyond that, it becomes a mess.
But as usual, it's horses for courses.
Well, my guess of 50 was mostly a reaction to the plague of heavy websites which do in JS what could've easily be done in CSS. IIRC the original intended use of JS was a few lines of scripts here and there, not a big application with dependencies.
@0 @zachdecook @sir
that someone puts a null or None in a place where it's not allowed, but nobody notices until it's passed to the other end of the code which rightfully assumes it's not a null and tries to access its member and it crashes.
It happens at runtime.
Only under certain conditions.
And the stacktrace contains no information about the function which introduced the null.
And it's not just null. Same can be said about variables/arguments assumed to be an object implementing some interface, having a member of particular name, etc. If you accidentally put there an object that doesn't match such requirements, you're unlikely to get an error right away pointing you to the place where things went wrong.
Now, C is only slightly better in that regard, same with C++. But anything from Go to Haskell has a strong enough static type system to catch most of those things at compile time.
1. Validate your inputs when they come from outside your program (from user, from files, from network, etc.)
2. Make types such that all valid inputs are of that type, and no invalid inputs are of that type. Any value of that type is valid by definition.
3. Validation in point (1) returns values of types from point (2) or error (eg. Maybe<ValidatedThing>, or Either<ValidatedThing, Error>) which you can then break down with a match statement.
Besides, type annotations make a great documentation.
When you're modifying a program, and you wonder "what is this `peer` variable and how can I get an IP address out of it", you can either:
a) Not have documentation. You can trace through all the code to find where that peer thing could come from, all the way to constructor, to figure out that it has an `inet_address` property so you extract an IP like this: `peer.inet_address`
b) Have outdated documentation, which says that the `peer` variable should be a tuple of `(ip, port)`. So you think that the right way to extract IP address is `peer` which then turns out to not work
c) Have types. (pls excuse invented syntax) The `peer` variable's type is declared in the function prototype 5 lines above like this: `peer: Connection`. You look at the top of your file, and see: `from .netutils import Connection`. So you know Connection comes from the netutils file in the current directory. You open that file, quickly find Connection's definition, and it truns out that it says:
inet_address : IPAddress
and now you know that `peer.inet_address` will exist, and will contain a valid IP address.
And it will never get outdated, because if someone tried to change what's being passed to that function without updating the type annotations in all the relevant places, the compiler would complain.
Yeah that addresses certain aspects of input validation, but by no means all.
Say that your ‘peer’ variable needs to be in your #LAN range and the latter can vary, perhaps even during runtime. All the static typing in the world is not going to help detect that situation so it is only an incomplete answer to the problem at hand.
I find it has its place but it's no silver bullet and can even introduce unnecessary complexity, e.g., in cases a duck typing approach is better suited.
Yes, it is one possible approach. Just by no means the only one nor inherently superior.
Especially since I started having to worry about the bigger picture, e.g. dealing with quality, finance and compliance issues, I have learned to stay away from dogmatic approaches.
E.g., from a personal perspective I intensely dislike Python; but I will use it when that's the best tool for the job under the circumstances (conversely, see above about #Lisp 😔).
@0 yeah, but a statically typed language gives you more tools IMO. Of course no type system is perfect, and in many cases a particular type system may in a way stand in your way.
And as you say, it all depends on usecase. I for one like Java and Haskell and yet I'm perfectly aware that they'd be a poor choice for many projects.
But I still think that unless you have very disciplined developers, a large project will on average require less maintenance burden if it's in statically typed language.
The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!