Hacker News new | ask | show | jobs
by AnimalMuppet 394 days ago
1. Dynamic typing says "anything I can do these operations on, I accept as input". This lets you accept input from code that doesn't have something that fits the strict definition of what input you were expecting.

2. Dynamic typing lets you change what shape your data is without having to change type annotations everywhere.

Problem is, I think both of these are deeply flawed:

1. If you're writing something nontrivial, you probably have several layers of nested function calls, some of which may be calls to libraries that are not yours. If you're saying "anything I can do these operations on, I accept", it becomes very difficult to say what the full extent of "these operations" are. Thus it becomes hard to say whether the caller is passing in valid input. You can "just try it", but that becomes hard if you care about it working in all cases.

2. Refactoring IDEs are a thing these days. You want to change the type signature? Press the button. Even better, it will tell you everything you broke by making the change - everywhere where you're doing something that the new type can't do. Without types, sure, you can just change it without pressing the button. Now try to find all the places that you broke.

It may be possible to construct a better steelman than I have done. For myself, even trying to steelman the position, I find it incredibly unconvincing.

4 comments

"Static typing is a powerful tool to help programmers express their assumptions about the problem they are trying to solve and allows them to write more concise and correct code. Dealing with uncertain assumptions, dynamism and (unexpected) change is becoming increasingly important in a loosely couple distributed world. Instead of hammering on the differences between dynamically and statically typed languages, we should instead strive for a peaceful integration of static and dynamic aspect in the same language. Static typing where possible, dynamic typing when needed!"

https://ics.uci.edu/~lopes/teaching/inf212W12/readings/rdl04...

But you can achieve #1 with typing.Protocol in type-annotated Python and traits in Rust. Fitting the "strict definition" sounds like nominal typing but you can opt in to explicit duck typing or structural typing while still being typed. (Someone correct me if I'm using these terms incorrectly.) In short you can still encode a lot of flexibility with types without just abandoning them alltogether.

And with #2, you can get that with static typing too... Let's say a method accepts an instance of an object `Foobar`. I can change the definition of `Foobar` ("change what shape [my] data is") without having to change type annotations everywhere.

I agree with you, I guess, that I find the steel man position unconvincing.

Refactoring IDEs were a thing back in the day.

"Less than 35 bugs were found in the 17,100 changes."

https://news.ycombinator.com/item?id=42473314

> Without types … Now try to find all the places that you broke.

Do failing tests show what we broke?

Yes, if you have tests that test all aspects of the behavior for all possible inputs.

Oh, you don't have that? Then do not scorn the help you can get from types.

"Less than 35 bugs were found in the 17,100 changes."

https://news.ycombinator.com/item?id=42473314

I wonder how many were not found.

Sometimes, but maybe you haven't written any tests! Type hints and immediate feedback from mypy are a lot easier than writing unit tests.
> haven't written any

Any!

Then maybe the immediate feedback of consistent types conveys a false impression.

Hard to conceive of a case where that would occur. Can you think of one?

The implication of what you're saying seems to be that if you're concerned about some kind of correctness you should be writing unit tests anyway and not being so fussed about type checking in a language like Python. I suppose if you are strictly following TDD that might work, but in all other cases type checks give you feedback much more quickly than unit tests ever can. I guess I don't understand.

Any old math with consistent types and incorrect calculation? (If only we'd diff'd the output with some known result.)

No doubt we're at cross purposes.

I'm a little surprised that you haven't mentioned — "Program testing can be used to show the presence of bugs, but never to show their absence!" (or existential versus universal quantification).

I'm afraid you lost me.