4 ms·
Actually OCaml has more operator stew than Haskell. Haskell's use of typeclasses/HKT avoids a lot of operator/function-name noise in the code. Where OCaml wins
by sidkshatriya 5y ago
Actually OCaml has more operator stew than Haskell. Haskell's use of typeclasses/HKT avoids a lot of operator/function-name noise in the code.
Where OCaml wins is that it does not hate mutation. This makes the code more impure but simpler. Sometimes just incrementing a mutable variable makes more sense than introducing a state monad!
- bitwize 5y agoYes, but is incrementing a mutable variable properly constrained and typed?
- deleted 5y ago[deleted]
- DonaldPShimoda 5y agoWhat does this even mean? OCaml's variables are immutable. To use mutation, you have to do so explicitly with the `ref` type, e.g.: let box = ref 0 in print_endline ("box value: " ++ int_of_string !box); box := !box + 1; print_endline ("box value: " ++ int_of_string !box) will print first `0` and then `1`. You cannot put a non-integer into the box because the box has type `int ref`, meaning only values of type `int` can be put into it with the `:=` operator.
- kccqzy 5y agoGP is (rhetorically, I assume) asking about whether or not the action of incrementing the mutable variable is typed, not that the variable itself is typed. For example in normal Haskell the code that uses mutation and code that does not use mutation have different types. A function may have the type f :: Int -> Int but with mutation it can become f :: Int -> ST s Int or f :: Int -> IO Int or f :: Int -> STM Int depending on the circumstances. That's not the case in OCaml. The kind of mutation in OCaml references is the most similar to Haskell's ST monad (not to be confused with State or StateT), but in Haskell the type tells us a mutation is happening inside the function call.
- bitwize 5y agoOne of the things that Haskell and monads bring to the table is typed side effects. Each action in a monadic computation has a type and cannot be freely mixed with other actions of different types. Of course, it's much easier and more convenient to go side-effecting willy nilly, as OCaml and imperative languages let you do, but that creates too many places for bugs to creep in and hide. Monadic programming gives you more control over what side effects are allowed when.
- ghostwriter 5y agoYou don't have to introduce a state monad to increment a mutable variable in Haskell, you can do that with IORefs pretty much the same way you do it in OCaml. But in a multi-core environment you will eventually want a guaranteed STM.
- sidkshatriya 5y agoYou are correct. However, IORefs are not idiomatic in "normal" Haskell. However, mutable variables are very much accepted in OCaml. Adding mutability to the mix via IORefs + Haskell's laziness by default means you don't _really_ know when a particular IORef mutation may really be executed. In OCaml, evaluation is eager and you know when it will happen. Even when you introduce bangs and special Haskell language extensions, fully removing laziness from your code in Haskell is difficult. TL;DR: Because of Haskell's laziness you are in some ways forced to be purely functional. OCaml allows you to embrace mutation in ways Haskell does not, in my view. > But in a multi-core environment you will eventually want a guaranteed STM. You actually may not always always want STMs. STMs are awesome but something more basic like locks may do the job. It can be more performant to use, say, a mutex. If STMs were superior on every parameter they would have taken over the world. They have not -- they are good in some scenarios and not so good in others...
- ghostwriter 5y ago> Even when you introduce bangs and special Haskell language extensions, fully removing laziness from your code in Haskell is difficult. Why would one prefer to fully remove laziness? > TL;DR: Because of Haskell's laziness you are in some ways forced to be purely functional. OCaml allows you to embrace mutation in ways Haskell does not, in my view. unless there's a strive to be more on the side of the Safe[1] language subset, Haskell can be told to embrace the same mutation property with a combination of `unsafePerformIO` and `seq`. People tend to avoid it because the language offers a tooling to achieve better mutation properties. Overall, my argument here is that OCaml's idiomatic approach to permissible mutations doesn't seem to be a competitive advantage when it comes to software development in general, but rather a flavour that imperative programmers prefer due to their familiarity with the concept. > You actually may not always always want STMs. Whenever there's a non-trivial retry policy, one should prefer to choose STM + queues over debugging adventures with Locks and Mutexes. Almost all of multithreaded software I can immediately think of have non-trivial retrying logic. [1] https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/safe_haskell.html https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/safe...
- yawaramin 5y agoI'd even argue that OCaml has way less operator stew than Haskell if we include Haskell's strictness annotations, type class instance selectors, and the large number of operators they have in the standard library. By comparison OCaml has a very modest number of operators.
- yodsanklai 5y agoI'd say OCaml wins in term of operators and maybe as a language until you start using monads. My entirely subjective feeling is that modern OCaml codebases use more and more monads, the language is becoming less elegant and tedious as a result.
- rackjack 5y agoModule hell?
- WastingMyTime89 5y agoThe introduction of let+ and let* made using monads fairly elegant in my opinion but this is a recent addition so you might have never seen it used. Outside of concurrent code monads are not that common in my experience.