Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> "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.

EDIT: refined type



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".

EDIT: 's/strong/powerful'


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.


> How would strong typing really prevent this?

calling print() would not have failed in a stronger type system.

However, calling print("foo") would resolve to window.print("foo") which should have failed because window.print takes zero arguments.


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.


Answers here focus on purely functional type systems, but more generally, this type of error can be caught by effect systems https://en.m.wikipedia.org/wiki/Effect_system


You cannot “window.print” in a Float32→Float32 function. It just won’t compile.


But of course, the function in question isn’t Math.Round. It’s “interpretDotNetFunction”. Which is, necessarily, “string -> IO ()” (forgive my syntax).


You could make it compile in Haskell. You just shouldn't:

f x = unsafePerformIO $ print "boom" >> return (pi * x)


In what language?


Haskell


You can't console.log either...


There is Debug.Trace.trace which does the trick with unsafePerformIO (which is a special non-type-safe escape hatch for IO)


I love this koan but I would replace 'strong' with 'pure'.

The fact that Float32 -> Float32 does not permit IO is due to purity. 'Strong' is kind of an ambiguous term here.


True, the term "strong" is maybe too strong here. Let's go with "powerful".


No, "pure function" is an actual term: https://en.wikipedia.org/wiki/Pure_function


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.


Are you referencing a specific situation or debacle?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: