> For people for whom coding is an iterative, exploratory process, forcing type declarations upfront is not just slower... it’s a no-go.
Is there any kind of programming task where it's too much to ask the programmer to know the type of the function he's writing?
The only place I can imagine types being a burden is in a REPL (it's just boring to write them every time), but even then optional types like Python and TS are an unequivocal win (you're presumably going to move your code out of the notebook/repl and into proper source files at some point).
> understating how easy dynamic typing makes substitutions
Yeah so easy they're easily wrong. One of the worst problems of dynamic languages is that they don't have the concept of an interface, which makes it harder and not easier to write generic code.
> everyone else is writing their class twice (interface + class)
That's caveman Java right there. Interfaces with defaults (Java, Kotlin, even C# has something similar IIRC) can easily emulate dynamic patterns like mixins while preserving type safety and without the diamond problem.
> Is there any kind of programming task where it's too much to ask the programmer to know the type of the function he's writing?
I think the problem is that lots of type systems are inherently limited, so there may be patterns that you want to express that your type system simply can't, or that you have to write tons of boilerplate code to express. In languages like Java or C# that don't have Sum types, this can be as basic as "this value is a String or Integer". You have to write a class hierarchy to express this in Java. In JavaScript you simply accept a parameter and branch on `typeof value`. More powerful type systems allow you to express more patterns, but you still have to type them out. This can be done, but if you're doing exploratory work an unknown dataset then this can make the work much slower. And there be may little benefit.
In C# you just declare them as dynamic if you wish to emulate the ways of JavaScript.
People keep forgetting Basic is dynamic and .NET was designed to support it as well, additionally it got improved with DLR classes to support IronPython and IronRuby projects.
So you can co type crazy in C#, F# and C++/CLI, or just get hold of those dynamic features.
Oh sure. But at that point you are using dynamic typing. My dream language is one that allows for full gradual typing, with the ability to opt functions in (opt out could also work) to strict type checking which gives you the safety and performance improvements where you want them, but allows you the flexibility of dynamic typing where you don't. PHP-style runtime type checks would be automatically generated at the boundaries between dynamically typed and statically typed functions.
One problem with gradual typing is that it has comparable performance overhead to dynamic typing: You can only optimize out dynamic type checks, dispatching, marshaling etc. if you have sizeable, self-contained portions of your program (i.e. modules) that only use static types! So the "graduality" of it goes mostly unused in practice.
It can be a useful pattern when designing interface boundaries across modules (e.g. ABI's, data interchange formats etc.) to allow for the required flexibility in a limited context where the overhead isn't going to matter all that much.
Performance is only half the point. The other half is correctness. And I think this pattern of "important correctness and performance sensitive core, surrounded by simple but flexible glue code" is common enough that such a language makes sense. It describes pretty much all of the code that I write at work in fact. Being able to simply add type annotations and have the compiler generate the runtime type checks would be wonderful.
Genuine question: what does old PHP’s (not the newer stronger versions) interfaces and “type” hints count as? It’s very much a dynamic programming language from what I remember of it, but interfaces were crucial to it when I was using it in anger.
Is it one of those in-between systems, just more on the dynamic side?
I have never used PHP professionally, but if you're talking about PHP 5 style interfaces, they are definitely a form of type checking, and they were introduced with the specific purpose of facilitating object oriented programming in PHP.
The point I'm getting at is that using interfaces lets you make guarantees about what methods the objects must have. I'm not really picky about what specific technical means are being used to enforce those, but passing an object of the wrong type to a method is an entirely avoidable category of errors, and I prefer them to be flagged by the compiler/interpreter/runtime/tsc/mypy/whatever as soon as possible.
IME well designed interfaces are even more important than well designed classes, and dynamic languages unfortunately make it harder to enforce interfaces. It's not by chance that the first thing Typescript did was to introduce interfaces.
Is there any kind of programming task where it's too much to ask the programmer to know the type of the function he's writing?
The only place I can imagine types being a burden is in a REPL (it's just boring to write them every time), but even then optional types like Python and TS are an unequivocal win (you're presumably going to move your code out of the notebook/repl and into proper source files at some point).
> understating how easy dynamic typing makes substitutions
Yeah so easy they're easily wrong. One of the worst problems of dynamic languages is that they don't have the concept of an interface, which makes it harder and not easier to write generic code.
> everyone else is writing their class twice (interface + class)
That's caveman Java right there. Interfaces with defaults (Java, Kotlin, even C# has something similar IIRC) can easily emulate dynamic patterns like mixins while preserving type safety and without the diamond problem.