> "But exactly which concrete bugs would a programming language and environment with a strong type system prevent?" asked the young student Master Typikos.
"These kind of errors." Master Typikos said - and she told the student the story about the time when a bug in a runtime caused Math.Round to do IO although it's type was `Integer -> Float32 -> Float32`.
The student did not believe this story. Later he was enlightened.
How would strong typing really prevent this? This is a side effect caused by a scoping issue, calling window.print instead of the local print function.
He means Haskell-grade types (float->float is not a function touching the IO monad). It wouldn't help in any mainstream language with actual types (like C++).
It's not the Math.Round function in the source text that's doing IO. IO is done as part of the function that gets run when you click "Run"
run : DotNetCode -> IO ()
Doing IO is expected for this function (not only might the source code to be executed do IO, but the print function that was intended to be called instead of window.print certainly would).
Assuming that the function was called with a string, but the window.print function doesn't accept a string argument, the typing systems in mainstream languages like Java (or even TypeScript) would catch this bug.
Right, that makes sense, I always thought that had more to do with the pure functional nature of Haskell than the type system, but I've never written any Haskell.
From a certain point of view that is the same thing. A pure function can only enforced using a powerful type system. Otherwise one could argue, your types are "lying".
Wow this suddenly made "get" the power of Haskell, which has escaped me for quite a while (not that I've ever actually written anything real with it). You can capture side effects _in the type system_. That is honestly brilliant.
calling print() would not have failed in a stronger type system.
That depends on the type system. The notation picozeta used suggests a Haskell-style system, where you wouldn't be able to call a function that does I/O from a function that is pure, which a type like `Integer -> Float32 -> Float32` would guarantee. You would need to explicitly permit I/O with a type like `Integer -> Float32 -> IO Float32` for the Round function for the call to print to compile in this sort of system.
Edit: Although it looks like the code that calls print in this case is actually another function, which might need to be in IO anyway if you were in this sort of type system, so maybe that doesn't help here.
But of course, the function in question isn’t Math.Round. It’s “interpretDotNetFunction”. Which is, necessarily, “string -> IO ()” (forgive my syntax).
Yesterday's static typechecks tells us nothing about today. You can typecheck against Chrome 75 all you like, yet Chrome 76 removes/renames/modifies at its pleasure - not to mention every other browser.
"These kind of errors." Master Typikos said - and she told the student the story about the time when a bug in a runtime caused Math.Round to do IO although it's type was `Integer -> Float32 -> Float32`.
The student did not believe this story. Later he was enlightened.
EDIT: refined type