1
votes

I suppose most purely functional programming languages have feature to control side-effects in function, such like monads in Haskell, but Elm doesn't require such feature due to TEA. Moreover, I hear Nim is an impurely functional programming language but it separates func and proc by with/without side-effects.

Then, I have a question. Is there any list of programming languages categorized by can or can't control side-effect in function? If not, could you give me some names of languages? I will search for name and study how it work, but I'm glad you to write it simply if possible. Following is list I know languages which can control side-effects and its way:

  • by monad
    • Haskell
    • PureScript
    • Idris
    • (After looking up some similar languages, I suppose Agda and Isabelle are included)
  • by algebraic effects (I don't understand it well)
    • Koka
    • Eff
  • by type
    • Clean
  • by syntax
    • Nim - proc and func

In addition, please let me know documents about controlling side-effects in function if you know.

1
The StackOverflow platform is not well suited for questions that ask for lists. - Bergi
Btw, to clear up some confusion, Haskell doesn't need monads to achieve IO. And most algebraic effects compose monadically as well. I would suggest you study those a bit more, as well as the papers about IO of the Haskell creators. - Bergi
Will the article contain the links to the papers? Anyway I will read it thoroughly, thanks! - Akihito KIRISAKI
Elm does not "avoid" monads. It uses them everywhere, it just does not mention them by name and it has terrible language support for them - saolof

1 Answers

-1
votes

Nope, your categorization is all wrong.

Haskell does not need IO to introduce side-effect and it can be easily done bypassing it. It also has error "Oops" concept that is not bound to IO a and can be used within pure functions. For example following definition is perfectly valid Haskell code:

myDiv1 :: Float -> Float -> Float
myDiv1 x 0 = error "Division by zero"
myDiv1 x y = x / y

More than that, you do not need any monad to handle an error. Consider Go with it's annoying

res1, err := somePackage.SomeOperationThatMightEndWithError()
if err == Nil {
    // do something with it
}
res2, err := somePackage.SomeAnotherDangereousOperation(res1) 
if err == Nil {
    // do something with it
}

It is not a monad. But it approaches purity by explicit error handling all over the codebase.

The same way of thinking can be applied to other categories you decided to list in the original post.