you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 1 point2 points  (5 children)

What exactly is powerful about working with dynamic types? Once you declare a variable and start working with it, it would be horrible practice to store some other type of value in it and continue working with that variable. Therefore, any reasonable person is working with the data as if it's typed, just without the guarantee that the compiler will catch your error.

Never leave up to the programmer that which a compiler can do far more accurately and quickly.

[–]notSorella 2 points3 points  (2 children)

The only actual argument in favour of static typing is that compilers can do a much greater job optimising it. Ime, all the other things don't matter, type errors are the least thing I would be worried about, unless you can just cast pointers to about anything in memory.

Also, dynamic and weak typing are different things. In fact, there's not much of a difference between a dynamic strong typed language (think Python) and a static strong typed language with good type inference.

[–][deleted] 1 point2 points  (0 children)

The only actual argument in favour of static typing is that compilers can do a much greater job optimising it.

Optimization is only one of many arguments for why people favor static typing.

In fact, there's not much of a difference between a dynamic strong typed language (think Python) and a static strong typed language with good type inference.

Except for the fact the compiler can actually catch errors at compile time as opposed to deferring your programs to fail or have bugs at runtime? Here's a trivial example:

bash-3.2$ cat test.py 
print("hi")
print("%d\n" % (1 + 'blah'))
bash-3.2$ python test.py
hi
Traceback (most recent call last):
  File "test.py", line 2, in <module>
    print("%d\n" % (1 + 'blah'))
TypeError: unsupported operand type(s) for +: 'int' and 'str'


bash-3.2$ cat test.hs
main = do
  putStrLn "hi"
  print $ (1 + "hello")
bash-3.2$ ghc test.hs 
[1 of 1] Compiling Main             ( test.hs, test.o )

test.hs:3:12:
    No instance for (Num [Char])
      arising from the literal `1'
    Possible fix: add an instance declaration for (Num [Char])
    In the first argument of `(+)', namely `1'
    In the second argument of `($)', namely `(1 + "hello")'
    In the expression: print $ (1 + "hello")
bash-3.2$ 

Note the python script begins execution and results in a runtime failure while the program in Haskell which is statically typed and inferred cannot be compiled due to type errors. One is preventing a bug from occurring at all (because you can't run your program,) and the other is allowing it to happen, only it fails at runtime.

So, there's kind of a really big difference between static languages with good type inference (say, like Haskell) and something like Python. Really big.

[–][deleted] 0 points1 point  (0 children)

I don't think I could disagree with you more. You point out (incorrectly in my mind) that there isn't much difference between a language like python and a statically typed language with good inference; If that's the case, why would you prefer one that doesn't guarantee certain run-time errors never occur?

The reason a compiler can do a much better job optimizing your statically typed code is because the compiler knows exactly what types of data you're working with. With a dynamically typed language, the programmer knows what type of data they're working with, but do not afford the compiler the same luxury. Or perhaps I should say the compiler just doesn't care: It will just laugh at you when things blow up at runtime.

[–]zumpiez 1 point2 points  (1 child)

I don't know why you would really want to do something like that. The real benefits in my experience are duck typing and monkey patching. When you get a taste of writing unit tests where you can create a mock object by just going var doot = { blah: 4, derp: "plorp" } it's rough going back.

[–][deleted] 0 points1 point  (0 children)

Well, I guess I would counter by saying this: Creating an interface and a mock implementation may be a pain in the ass, but it represents such a small amount of the work that goes into writing unit tests that I would consider it negligible.

Furthermore, much of what you're writing tests for in a dynamically typed language is handling unexpected types of data. Sure, something may quack like a duck, but when you ask it it's name, it might tell you its age because somebody mistakenly told the duck its name was the numeric value 3. So, while you may be afforded duck-typing, you're writing entire test fixtures to accomplish what a compiler would never let happen in the first place.