4 ms·
Your statement reminds me of the spoon scene in The Matrix: Instead of trying to bend the code to fit within the confines of its types simply try to realize th
by riskable 3y ago
Your statement reminds me of the spoon scene in The Matrix: Instead of trying to bend the code to fit within the confines of its types simply try to realize the truth... Static types are just more code. They're extra conditions that we apply to things like function signatures and variable definitions instead of adding conditional checks where it matters.
"Aha!" you say, "but by enforcing conditional checks at variable definition and inside function signatures we don't have to check them ourselves in our code and the compiler itself can check them to ensure correctness and optimize performance!"
...and I'd agree with that sentiment but I'd also add that by having to reason about your types constantly you're adding a non-trivial amount of mental overhead when structuring your code. For some people that's how they reason about their code anyway but for others, having to consider whether or not a number is a `u8`, `u32`, or `usize` adds a lot of complexity to the code that could very well be entirely unnecessary depending on the use case.
Consider, for example a program that's meant to be executed on the command line that takes two numbers and adds them together. No matter what language you use you have to convert the raw string input into a numerical type before performing the addition.
In Python you have a simple function, `int()` that will happily turn any string consisting of numbers into a proper integer that can be used for math operations. If it gets something that isn't a number it'll throw an exception which is trivially easy to detect and wrap in a `try`/`except` block with a user-friendly error message. If we wanted to support floating point numbers we could just use `float()` and the code would otherwise be exactly the same.
In strongly-and-statically-typed languages this same process involves considerably more overhead. Before we can select a function to convert a string into a number we must first pick a numerical type and before we can do that we must think real hard about how big of a number we're going to support in this application. Our function signature(s) could also get complicated because, "wait: what type of string are we going to get from the command line?" Something as simple as adding two numbers becomes complicated really quickly!
Comparing the two ways of handling things (strongly, statically typed VS strongly, dynamically typed), Python ends up the clear winner a lot of the time because you got the job done without having to think as much, with less code that's super easy to reason about even though it didn't use static typing.
The other problem is that when you write such trivial programs in strongly, statically-typed languages like C, C++, Rust, etc it requires a lot more mental overhead to look at the code to figure out what's going on/how it works (though with Rust, less so because there's not 1001 awful ways to do things haha).
- handsaway 3y ago> Before we can select a function to convert a string into a number we must first pick a numerical type Except this has literally nothing to do with static typing and everything to do with whether or not the language you're using cares about numeric types. For instance in typescript you'd just have `number` as the type. You could conceive of a dynamically typed language like python where adding a u8 to a u32 would cause a runtime error. In which case it sure would be nice to have the compiler tell you to convert before you called a function. >The other problem is that when you write such trivial programs If only I had a career writing trivial programs that would make a lot of things easier.
- valcron1000 3y ago> In Python you have a simple function, `int()` that will happily turn any string consisting of numbers into a proper integer that can be used for math operations. For starters this is not the case, it does not work on a string of numbers: >>> int("123 890 123") Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: '123 890 123' > Before we can select a function to convert a string into a number we must first pick a numerical type and before we can do that we must think real hard about how big of a number we're going to support in this application Aren't you doing the exact same thing in Python by picking `int()` over `float()`? > what type of string are we going to get from the command line? Well, this might be the case for system languages, but most have a single `String` type. Here is the program you described in Python def main(): n1 = input() n2 = input() sum = int(n1) + int(n2) print(sum) And here it's in Haskell main = do n1 <- getLine n2 <- getLine let sum = read n1 + read n2 print sum Accepting a single line of numbers is not much different main = do nums <- words <$> getLine let res = sum $ map read nums print res I didn't think much about it, it's not a lot of code and I guess it's easy to reason about?