News for hackers. Stuff that matters.
Re:Partial functions and total functions by skybrian on Wednesday December 15, 2021 @04:00PM (#29571554)
We use type systems to find bugs when dependencies are upgraded, and performance not being part of the contract between modules means that performance degradation won’t be caught by the type system.

You can deal with it in other ways like running benchmarks often, but I hope you can see why it might be nice in principle if such implicit contracts were made explicit and checked by the compiler? For example, it might make hard realtime systems easier to build and upgrade if there were some formal way of reasoning about deadlines. I haven’t heard of it ever being made practical, though.

Also, I was thinking of Haskell rather than Java as a language where adding logging would change a function’s type signature.

There’s a basic difference between functions that can fail (returning an error) and those that are considered to always succeed (so no error) which I think is well-captured by a type system, whether you do it like Go or Rust or functional languages. If there is any kind of error then you can catch it without distinguishing between them. The same could be done using exceptions too.

The problem with Java is that they tried to distinguish further by what kind of error can be thrown, and this sort of turned into a bad effect system. There are methods that throw IOException and can do I/O and others that throw SQLException so they can talk to a SQL database, and, uh, don’t those categories overlap? And isn’t this exposing implementation details? Why should the caller care whether you use a SQL database or not?

I suspect more principled effect systems might end up having similar problems with functions being inflexibly incompatible due to having different effects, as described in What Color Is Your Function for the sync versus async distinction.

There are no comments on this comment yet.