Comment by mrkeen

2 years ago

> you end up needing to propagate a bunch of extra stuff everywhere.

Declaring a function as non-IO is a contract to your callers that you don't do IO. You don't need to do it. You can write everything in IO if you choose. You can also call into the wonderful ecosystem of libraries, because IO functions can call other IO functions, as well as non-IO functions.

There is only ever friction if you declare your function to be IO-free. If you declare your function to be IO-free, but call IO from inside it, it's a compile error because of course it is.

So why bother declaring anything IO-free? If you do arbitrary IO in a Parser, you can't back-track. If you do arbitrary IO in Parallel code, you invite race conditions. Transactions is my favourite example, though:

  .NET [1]
  > Disillusionment Part I: the I/O Problem
  > It wasn’t long before we realized another sizeable, and more fundamental, challenge with unbounded transactions [...] What do we do with atomic blocks that do not simply consist of pure memory reads and writes? (In other words, the majority of blocks of code written today.) This was not just a pesky question of how to compile a piece of code, but rather struck right at the heart of the TM model.

  Scala: [2]
  > ScalaSTM does not have the goal of running arbitrary existing code, which is where most of their problems arose.

  Java/Akka: [3]
  > STM is considered as a failed experiment

  Clojure: [4]
  > Very simply the side-effects will happen again. In the above case this probably doesn’t matter, the log will be inconsistent but the real source of data (the ref) will be correct.

Sorry for the rant, but I really needed to highlight the fact that nonIO-calling-IO is not some language design flaw created by out-of-touch academics. It's a fundamental problem.

[1] https://joeduffyblog.com/2010/01/03/a-brief-retrospective-on...

[2] https://nbronson.github.io/scala-stm/faq.html

[3] https://groups.google.com/g/akka-user/c/3JWz-X5dbe8/m/YiV4WF...

[4] https://sw1nn.com/blog/2012/04/11/clojure-stm-what-why-how/