4

Recently I am reading some functional programming books involving Haskell.

It seems Haskell quite fancies “modular programs”, for example,

f :: (Integer,Integer) -> Integer
f = sum . map sq . filter . odd . between

even though the same function can be written like

f' (m, n) = go m
  where go m | m > n = 0
             | otherwise = go (m + 1) + if odd m then sq m else 0

Also “fusion laws” are quite popular and used (http://www.cs.ox.ac.uk/ralf.hinze/publications/IFL10.pdf)


I am not an OCaml expert, but I would use fold_left or fold_right if possible and easy and efficient (for example, anyway I have to scan the whole list and won't stop in the middle).

However, at most of the time, I will write explicit recursive code using “pattern matching”.

Also I read quite some OCaml projects in github and explicit recursive seems are very usual.

In addition, I never heard of fusion law for OCaml.


My questions are

  1. Is OCaml the same that it prefer modular programs like shown above in Haskell?
  2. Does OCaml also have fusion laws?
  3. If I want to be an OCaml professional, should I really care or learn from Haskell's fusion laws?
leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
Jackson Tale
  • 25,428
  • 34
  • 149
  • 271

2 Answers2

7

Fusion is not as easy to implement in OCaml as it is in Haskell due to side-effects. If you were to go ahead and fuse functions in OCaml in the same way that GHC fuses them, then you would get very unpredictable results, and side-effects happening in a different order than how you wrote the program. So, no, OCaml doesn't have "fusion laws", as you put it. That doesn't mean it's impossible to do fusion in OCaml, you just have to work harder.

Compilers for imperative languages sometimes implement loop-fusion, which has a similar effect to fusion in Haskell. OCaml could benefit from loop-fusion but it's a much more involved optimization to implement.

Fusion is a very good example of one of the benefits of not having side-effects in Haskell. It makes certain optimizations much easier to implement and they can give much stronger guarantees about when the optimization trigger.

I don't think you need to know that much about fusion in order to be an effective OCaml programmer.

svenningsson
  • 4,009
  • 1
  • 24
  • 32
  • In the example above, if the explicit recursive code has better performance, should I still prefer modular codes using `fold_left`, etc, to make the meaning more obvious? – Jackson Tale Jan 09 '14 at 23:23
  • It depends. Readability is usually preferrable but performance sometimes beats it. Time your code and decide. – camlspotter Jan 10 '14 at 03:59
  • So if my code has pure functions, I should be able to fuse those. It sounds like you say that in practice. Most functions that would benefit would not be written as pure functions. It's that right? – Arturo Hernandez Apr 04 '16 at 03:51
3

In my personal view, fusion simply goes against OCaml's (undocumented) philosophy: keep the compiler simpler as possible, and what you write is what you run.

This sounds very boring once you learn what Haskell(GHC) does (or is force to do) to achieve its speed under more challenging lazy+pure settings. But many industrial OCaml users buy this simplicity, since it keeps the compiler pretty fast and it is easier to predicate the performance change of your code modification in OCaml. For example Yaron Minsky has answered the same thing recently in InfoQ: link to the article

That said, I must confess that sometimes I want to have fusion like optimization in OCaml, especially when my huge function compositions get slower. I sometimes like OCaml simplicity and sometimes like Haskell's cool optimizations.

My answers:

  1. No. OCaml stdlib has no function composition operator, and I guess it is intentional.
  2. No. If you really need code transformation you do it manually, or write your own transformation hack with camlp4 or compiler-libs.
  3. OCaml does not perform fusions, but knowing what fusion does to achieve performance will help you to optimize your OCaml code.
int3
  • 12,861
  • 8
  • 51
  • 80
camlspotter
  • 8,990
  • 23
  • 27