5 ms·
Roughly stuff like templating, abstract base classes, generics and non-trivial user defined types. Consider a simple program that adds 2 numbers: a & b togethe
by ReflectedImage 3y ago
Roughly stuff like templating, abstract base classes, generics and non-trivial user defined types.
Consider a simple program that adds 2 numbers: a & b together. In a dynamically typed language, this would be a + b. In a statically typed language, once you consider overflow and underflow, you will likely have a hundred lines of code.
This creeps up again in JSON parsing where the types really are defined at runtime.
But the most general case is people creating complex and hard to understand types in their code, which they then export to unsuspecting developers to use. e.g. The type of stuff that forced C++ to introduce the auto keyword.
- paulmd 3y ago> In a dynamically typed language, this would be a + b. In a statically typed language, once you consider overflow and underflow, you will likely have a hundred lines of code. https://stackoverflow.com/questions/52376716/c-overloading-of-the-plus-operator https://stackoverflow.com/questions/52376716/c-overloading-o... literally a single line of code to overload an operator. anyway, if you don't consider error states in your dynamic implementation and you do this in static then yes, it could be simpler. But static doesn't force you to consider error conditions - just like this C++ example does not. and yes, if you fall back on javascript notions of default cross-type arithmetic (1 + "1" = ?) then you will get something, and if you take great care to structure your code you may get something useful as a side-effect, but, this is not meaningfully different from the error-state for most people. Getting [] or "11" isn't the expected outcome unless you've come to expect that quirk of javascript, and is something that a static compiler would rightfully complain about - because a user asking for an undefined operation computed across incompatible types seems like a classic type error. If it's not, then just define the operators that are meaningful to you - and you could define it as an interface if you wanted it to work with a bunch of classes etc. Again though, the complaint elsewhere that "a lot of this debate just ends up being dynamic programmers who are unaccustomed to using static types at all and think it must be so super burdensome all the time" seems pretty accurate. Defining custom operators is not something that occupies even 1% of my time in any static language.
- ReflectedImage 3y agoThe code you posted is incorrect and full of bugs. For example, if A is 9223372036854775807 and B is 10, then you will get the incorrect answer. Try it out if you don't believe me. Another example is A is -9223372036854775807 and B is -10. Again you will get an incorrect result. Once you finish fixing these bugs it will be at least 100 lines long. The dynamically typed version of the code is just A + B. "a lot of this debate just ends up being dynamic programmers who are unaccustomed to using static types at all" Static typing is objectively the inferior approach. It's just that people are too lazy to learn how to code with two different typing systems. Overall statically typed programmers only code at 1/3 of the speed as their dynamically typed counterparts. Of course, if you have only ever done statically typed programming, you are not going to understand how bad it is in comparsion.
- therealdrag0 3y agoThat doesn’t sound like it’s typings fault at all. That’s a language design choice. Typed languages have types that handle adding numbers of all sizes same as dynamic typing. In fact JavaScript numbers aren’t magic, they are 64bit doubles, which have their own strange behavior and special cases, many of which could be considered “incorrect”. You’re acting like dynamic typing solves problems that it doesn’t solve.
- ReflectedImage 3y agoYou have errors coming from using static types. Static typing blew up a space rocket, if you weren't aware. JavaScript is terrible because it was built over 3 decades by different competing browser vendors.
- ReflectedImage 3y agoI think we are at max reply depth but here is the trivial dynamically typed solution to the problem: https://pastebin.com/UZvB5YD1 https://pastebin.com/UZvB5YD1 It's a little bit simpler than anything you will get in an statically typed language. It works for integer and floats of any size. It even works for lists! You can't do that in a statically typed language without a ton of code.
- tremon 3y agoonce you consider overflow and underflow You're explicitly comparing apples and oranges here. Are you implying that it's never necessary to check for overflow and underflow in dynamically typed languages, and that it's somehow mandatory to do so in statically typed ones? Or, in case your argument is "numbers in dynamically typed languages do not overflow", are you aware of BigDecimal in Java or sys.maxint in Python 2?
- ReflectedImage 3y agoIn modern dynamically typed languages, you do not need to check for overflow or underflow and you don't need any special library to do so, it's built directly into the language.
- nyssos 3y ago> templating Yes, running arbitrary code at compile-time can produce arbitrarily complicated results if you're not very very careful. This is not a type system issue: lisp macros are just as dangerous. > abstract base classes Again, nothing to do with types: your complaint is with Java-style OO. Which is garbage, but for historical Java-specific reasons. Using Java as your prototypical example of a typed language is like using PHP as your prototypical example of a dynamic language. There's no such thing as a feature good enough to rescue a bad language. That doesn't mean no feature of a bad language can ever be good. > generics Generics produce strictly simpler code than copy-pasting the same implementation over and over again. That's their entire purpose. A generic function isn't a way to give the same name to different pieces of code (the way that inheritance is, for instance), it's literally one function: `mapIntList` is `mapFloatList` is `mapStringList` is `mapIntListList`, all the way down to the compiler output. Unless you're doing some pretty serious performance optimization, giving them different implementations is a bug. And you wouldn't do so in a dynamic language either! > non-trivial user defined types These exist as part of your program structure whether you like them or not, the only question is whether they've been made explicit. > Consider a simple program that adds 2 numbers: a & b together. In a dynamically typed language, this would be a + b. In a statically typed language, once you consider overflow and underflow, you will likely have a hundred lines of code. Considering overflow and underflow in the static case but not the dynamic case is stacking the deck. Either you're using arbitrary-precision numbers or you're not. Here's Haskell code for adding two numbers: add :: Num x => x -> x -> x add a b = a + b If you don't want to worry about overflows, you use `Integer`s, which are arbitrary precision. If you're worried about performance, you use `Int`s, which are machine integers. You can complain that this isn't "really" the addition code, since we're calling out to the `Num` instance, but the same applies to dynamic languages. Python's `a + b` is calling out to `__add__` in exactly the same way. > This creeps up again in JSON parsing where the types really are defined at runtime. They are not. The type of arbitrary JSON is (using Haskell again) data JSON = | JSONNull | JSONBool Bool | JSONNumber Double | JSONString Text | JSONArray [JSON] | JSONObject (HashMap Text JSON) (You don't have to use a hash map, of course: decoding the raw text stream to JSON is a separate step). You then check that it has the structure you expect by implementing a function `jsonToFoo :: JSON -> Either MyPreferredErrorType Foo`.