What are the alternative of monads to use IO in pure functional programming?
Asked Answered
O

7

39

monads are described as the haskell solution to deal with IO. I was wondering if there were other ways to deal with IO in pure functional language.

Ossify answered 28/1, 2010 at 21:22 Comment(1)
You can build an interpreter for an embedded DSL using ADTs or GADTs that only allows the effects you want. Maybe with the use of quasi/quotes you can reuse a lot of the Haskell syntax tree... IO Actions would either run inside your embedded DSL, or they would transform the parse tree of your eDSL...Schouten
M
38

What alternatives are there to monads for I/O in a pure functional language?

I'm aware of two alternatives in the literature:

  • One is a so-called linear type system. The idea is that a value of linear type must be used exactly one time: you can't ignore it, and you can't use it twice. With this idea in mind, you give the state of the world an abstract type (e.g., World), and you make it linear. If I mark linear types with a star, then here are the types of some I/O operations:

    getChar :: World* -> (Char, World*)
    putChar :: Char -> World* -> World*
    

    and so on. The compiler arranges to make sure you never copy the world, and then it can arrange to compile code that updates the world in place, which is safe because there is only one copy.

    The uniqueness typing in the language Clean is based on linearity.

    This system has a couple of advantages; in particular, it doesn't enforce the total ordering on events that monads do. It also tends to avoid the "IO sin bin" you see in Haskell where all effectful computations are tossed into the IO monad and they all get totally ordered whether you want total order or not.

  • The other system I'm aware of predates monads and Clean and is based on the idea that an interactive program is a function from a (possibly infinite) sequence of requests to a (possibly infinite) sequence of responses. This system, which was called "dialogs", was pure hell to program. Nobody misses it, and it had nothing in particular to recommend it. Its faults are enumerated nicely in the paper that introduced monadic I/O (Imperative Functional Programming) by Wadler and Peyton Jones. This paper also mentions an I/O system based on continuations which was introduced by the Yale Haskell group but which was short-lived.

Messier answered 28/1, 2010 at 22:55 Comment(7)
Sequencing via monad binding is pretty much just type-checked continuation-passing style anyway, isn't it? My impression was that monads and continuations are mostly interchangeable, except that continuations are decidedly not, in general, either warm or fuzzy.Fireworks
Continuations form a monad but monads are decidedly not continuations. CPS is way more powerful because you're allowed to make copies of things (including continuations!). Monads restrict things much more severely than mere type-checking.Messier
"Monads are decidedly not continuations" - no, but the relationship isn't just an InstanceOf one. Cf. lambda-the-ultimate.org/node/3235 Lawvere Theories and Monads, Hyland & Power, 2007.Kizzie
Haven't had the time to read that Wadler & Jones paper yet, but I'm curious--any examples of something that could be done with real continuations (without wrecking type safety or referential transparency) that can't be done with the Cont monad? Obviously there are many unsafe things that continuations enable, but a hypothetical Haskell-with-call/cc would presumably disallow those anyway. Or if this is discussed in the paper, I'll make time to read it this weekend...Fireworks
How does the linear type system work with concurrency?Impercipient
I'm pretty sure the statements "Nobody misses [dialog-based I/O], and it had nothing in particular to recommend it" are unconditionally false. I would omit them, and I would definitely avoid citing a single paper (by partisans of another I/O system!) as evidence for them. Dialogs have several advantages which are difficult/impossible to recover with GHC's implementation of the IO monad (although implementing IO on top of dialogs instead would give you the best of both worlds).Kuban
isn't the Dialog type the exact opposite of what you show? a user program makes (produces) requests of the run-time system, and gets back its responses from it.Mauldin
P
9

Besides linear types, there's also effect system.

Pembrook answered 7/2, 2010 at 7:30 Comment(0)
F
7

If by "pure" you mean "referentially transparent", that is, that an applied function is freely interchangeable with its evaluated result (and therefore that calling a function with the same arguments has the same result every time), any concept of stateful IO is pretty much excluded by definition.

There are two rough strategies that I'm aware of:

  • Let a function do IO, but make sure that it can never be called twice with the exact same arguments; this side-steps the issue by letting the functions be trivially "referentially transparent".

  • Treat the entire program as a single pure function taking "all input received" as an argument and returning "all output produced", with both represented by some form of lazy stream to allow interactivity.

There are a variety of ways to implement both approaches, as well as some degree of overlap--e.g., in the second case, functions operating on the I/O streams are unlikely to be called twice with the same part of the stream. Which way of looking at it makes more sense depends on what kind of support the language gives you.

In Haskell, IO is a type of monad that automatically threads sequential state through the code (similar to the functionally pure State monad), such that, conceptually, each call to an otherwise impure function gets a different value of the implicit "state of the outside world".

The other popular approach I'm aware of uses something like linear types to a similar end; insuring that impure functions never get the same arguments twice by having values that can't be copied or duplicated, so that old values of the "state of the outside world" can't be kept around and reused.

Fireworks answered 28/1, 2010 at 21:46 Comment(2)
For examples of the first approach, see F. Warren Burton's Nondeterminism with Referential Transparency in Functional Programming Languages.Transarctic
Your second rough strategy defines even a C program as a purely functional one! :-DGuam
C
6

Uniqueness typing is used in Clean

Cadi answered 28/1, 2010 at 21:31 Comment(0)
I
6

Imperative Functional Programming by Peyton Jones and Wadler is a must read if you are interested in functional IO. The other approaches that they discuss are:

  • Dialogues which are lazy streams of responses and requests

type Dialogue = [Response] -> [Request]

main :: Dialogue

  • Continuations - each IO operation takes a continuation as argument

  • Linear types - the type system restricts you in a way that you cannot copy or destroy the outside state, which means that you can't call a function twice with the same state.

Interdependent answered 28/1, 2010 at 22:53 Comment(0)
C
5

Functional Reactive Programming is another way to handle this.

Capitalistic answered 29/5, 2014 at 18:10 Comment(2)
I've never heard the term "Function Reactive Programming". Can you change it to "Functional Reactive Programming"? Great answer otherwise.Annunciation
No problem, thanks for noticing. No idea how I misspelled that one.Capitalistic
T
1

I was wondering if there were other ways to deal with IO in a pure functional language.

Just adding to the other answers already here:

  • The title of this paper says it all :-)
  • You could also look at:

Rebelsky S.A. (1992) I/O trees and interactive lazy functional programming. In: Bruynooghe M., Wirsing M. (eds) Programming Language Implementation and Logic Programming. PLILP 1992. Lecture Notes in Computer Science, vol 631. Springer, Berlin, Heidelberg

  • When Haskell was young, Lennart Augustsson wrote of using system tokens as the mechanism for I/O:

L. Augustsson. Functional I/O Using System Tokens. PMG Memo 72, Dept Computer Science, Chalmers University of Technology, S-412 96 Göteborg, 1989.

I've yet to find a online copy but I have no pressing need for it, otherwise I suggest contacting the library at Chalmers.

Transarctic answered 4/6, 2020 at 23:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.