9

I've had a look at the algo.monads and fluokitten documentation. I've also read through monad blog entries by Jim Duey, Konrad Hinsen and Leonardo Borges.

The closest I can find is Konrad Hinsen's library Monadic IO streams - but this doesn't appear to 'implement the monad interface' (for want of a better phrasing)

This is example using ST in Haskell

oneST :: ST s Int -- note that this works correctly for any s
oneST = do var <- newSTRef 0
           modifySTRef var (+1)
           readSTRef var

one :: Int
one = runST oneST

My question is: Is it possible to do the IO Monad from Haskell in Clojure? Could you provide an example?

hawkeye
  • 34,745
  • 30
  • 150
  • 304
  • Isn't Clojure a dynamically typed language? What would be the benefit of monads like IO or ST then? Throwing exceptions on illegal operations? Taken, this might be better than having to cope with the effects of illegal operations later in the program flow. – ziggystar Feb 17 '14 at 11:21
  • 3
    What are the specific features of Haskell `IO` that you want to reuse within Clojure? – Gabriella Gonzalez Feb 17 '14 at 11:31
  • It's possible, but due to the lack of reliable tail calls in Clojure, I doubt it's terribly practical. – lpsmith Feb 17 '14 at 13:37
  • 1
    @lpsmith, can you elaborate on what you mean by "reliable tail calls"? – Jason Sperske Feb 17 '14 at 20:41

1 Answers1

16

There are a few ways to answer this question.

Yes

  • Trivially: Think of IO as a monad transformer that grants the special permission of working with side effects. Then any monad in Clojure is an IO monad, as performing side effects is not a privileged operation in Clojure.

  • Fatuously: Clojure is Turing-complete, so you could implement all of Haskell, including the IO monad in Clojure. Haskell is Turing-complete, so you could implement all of Clojure in Haskell and expose the IO monad.

No

  • Philosophically: The essence of the IO monad, preserving purity while integrating with the type system, is incompatible with Clojure's impurity and dynamic typing. Any attempt to shoehorn in the IO monad would either be at odds with Clojure's philosophy or fail to capture the essential point of having an IO monad.

Maybe

  • Partially: The monadic-io-streams library linked to in the question is intended for use with the algo.monads library, or its predecessor. The monadic interface is the state monad. Monadic-io-streams provides some jailed IO monadic functions to work with it. This does not prevent you from using any other functions with side effects, and without a type system integrating IO there is no systematic way to say which is which. This is not the IO monad; it just does a few things similar to the IO monad. This is interesting but of dubious utility.

  • Someday: There is interest in Typed Clojure. If side effects are added to the type system, then it may become desirable to isolate them in a structured manner for some purposes and give reason for the existence of something like an IO monad in Typed Clojure.

A. Webb
  • 26,227
  • 1
  • 63
  • 95
  • 2
    I'm not a Monad expert, but I don't see why you say it can be partially done. What in the IO Monad is reliant on static types? From my perspective nothing. That you are not forced to do IO exclusively through the IO Monad doesn't make it you can't implement the IO Monad. Even Haskell has unsafePerformIO. So why not move that to Yes - foolishly (and maybe mention instead that you can, but it wouldn't be super awesome to do so in Clojure, and you could easily break the benefits of it by accident). – Didier A. Nov 27 '19 at 19:09