CGPA nyaa~
:: Cat Girl Program Analysis :: est. unknown :: powered by Rabbithole
๐Ÿ  Index โš”๏ธ Lang Wars ๐Ÿ“ Type Theory ๐Ÿ”ฎ Proofs ๐Ÿ”ง Tooling ๐Ÿฑ Members ๐Ÿ” Search
Logged in as: MeownadTransformer | Profile | Logout
๐Ÿ—ก๏ธ OCaml vs Haskell: A Civilized Discussion
๐Ÿ“Œ Category: Language Wars Containment Zone ๐Ÿ’ฌ Replies: 47 ๐Ÿ‘ Views: 6,221 โฐ Started: 2024-11-03 02:14 UTC ๐Ÿ”ฅ Status: ACTIVE (barely)
โš ๏ธ MODERATOR NOTE: This thread has been relocated from General Discussion to Language Wars Containment Zone. Please keep it civilized. โ€” PurrfectModerator
Currently viewing this thread: CamelCat, MeownadTransformer, GaloisCat, CurryCat, 14 guests
#1
CamelCat
OCaml Supremacist
๐Ÿช๐Ÿฑ
Posts: 3,517
Joined: 2019-03-12
Rep: โญโญโญโญโญ
OP
Jane Street Fangirl

Fellow cat girls of the functional persuasion, I have had it up to here with the Haskell propaganda machine. It is time for a civilized, measured, and completely unbiased discussion. I will go first.

OCaml is simply better. I will now enumerate the reasons with the rigor befitting this esteemed community.

1. PRAGMATISM vs IVORY TOWER NONSENSE

OCaml is impure and strict. You can do effects anywhere you want. You do not need to wrap your entire life in an IO monad just to print "nya~" to stdout. Real programs have side effects and OCaml respects that.

2. THE MODULE SYSTEM

OCaml's module system โ€” with first-class modules, functors, and module signatures โ€” is a tour de force of language design. It gives you parameterized abstractions without needing the entire MTL stack and 47 language pragmas. You get explicit, readable, traceable code structure.

(* OCaml: clean, explicit, sane *) module type ORDERED = sig type t val compare : t -> t -> int end module Make (Ord : ORDERED) = struct let sort lst = List.sort Ord.compare lst end

3. OCaml 5 ALGEBRAIC EFFECTS

We don't need monads anymore. OCaml 5's algebraic effects let you write direct-style async code without the let*-hell that even we OCaml people admit is a little cumbersome. Eio is beautiful. The future is now.

4. PERFORMANCE

Strict evaluation = predictable performance. No thunks leaking memory at 3am. No needing to annotate ! everywhere because GHC decided your integer is now a lazy box of sadness. See benchmarks thread.

Haskell people, your rebuttal please. Keep it civilized. (=^.^=)

-- CamelCat | OCaml Supremacist | Jane Street Fangirl /\ /\ ( ` ` ) "let () = print_endline \"nyaa~\"" \ ๐Ÿช / compiles in 0.3s. deal with it. \___/ cgpa.isarabbithole.com/profile/camelcat
๐Ÿ‘ Quote โœ๏ธ Edit ๐Ÿšฉ Report
#2
CurryCat
Monad Enjoyer
๐Ÿ›๐Ÿฑ
Posts: 2,841
Joined: 2020-07-05
Rep: โญโญโญโญ
GHC Contributor
CamelCat wrote:
You do not need to wrap your entire life in an IO monad just to print "nya~" to stdout.

Ah yes, the classic "I don't want to think about effects" argument. Let me introduce you to the concept of correctness, darling. nyaa~

Haskell's purity is not ivory tower nonsense โ€” it is a guarantee. When a function has type Int -> Int, it actually just takes an Int and returns an Int. No hidden HTTP calls. No secretly writing to a file. No mutating global state while you're not looking. The type IS the spec.

-- Haskell: pure, honest, elegant -- This function CANNOT have side effects. The compiler GUARANTEES it. pureComputation :: Int -> Int pureComputation x = x * x + 42 -- Effects are tracked. Always. No surprises. nyanPrint :: IO () nyanPrint = putStrLn "nya~ (=^.^=)"

Also, do-notation is beautiful. It reads like imperative code but with the full power of monadic sequencing. Your let* in OCaml is literally just a sadder version of this. You are doing monads poorly without calling them monads.

As for type classes vs module system: I wrote 4000 words on this but the short version is โ€” type classes give you ad-hoc polymorphism with implicit dispatch. OCaml modules force you to carry dictionaries manually like some kind of 1995 programmer. The ergonomics are simply not comparable.

Lazy evaluation is also a feature, not a bug. Infinite lists are purring elegance. [1..] just works. When did you last produce a lazy infinite stream in OCaml without a library? Exactly.

-- CurryCat | "a monad is just a monoid in the category of endofunctors nyaa~" /\ /\ ( ^ ^ ) Haskell: where your program either doesn't compile \ ๐Ÿ› / or is correct. no in-between. \___/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#3
CamelCat
OCaml Supremacist
๐Ÿช๐Ÿฑ
Posts: 3,517
Joined: 2019-03-12
Rep: โญโญโญโญโญ
OP Jane Street Fangirl
CurryCat wrote:
do-notation is beautiful. It reads like imperative code but with the full power of monadic sequencing.

I love how Haskell people brag about do-notation making things "read like imperative code" as if that's a selling point for a pure functional language. You invented a complicated system specifically to escape it... only to make it look like what you escaped. (=^โ—ก^=)

OCaml has let* (binding operators since 4.08) and it works perfectly well, thank you:

(* OCaml let* โ€” perfectly readable, no PhD required *) let ( let* ) = Option.bind let safe_div a b = let* x = Some a in let* y = (if b = 0 then None else Some b) in Some (x / y)

Also re: performance โ€” I ran the n-body simulation benchmark last week. OCaml native: 1.4s. GHC with -O2: 4.1s (space leak, had to add BangPatterns everywhere like a caveman). The OCaml result was predictable. The Haskell result required archaeology to fix.

The OCaml compiler is "way simpler and produces code with more predictable performance" โ€” this is just factual. Meanwhile Haskell programs require you to understand the entire GHC optimization pipeline just to get reasonable runtime behavior. That is not a feature. That is a tax.

-- CamelCat | OCaml Supremacist | Jane Street Fangirl /\ /\ ( ` ` ) "let () = print_endline \"nyaa~\"" \ ๐Ÿช / compiles in 0.3s. deal with it. \___/
๐Ÿ‘ Quote โœ๏ธ Edit ๐Ÿšฉ Report
#4
CurryCat
Monad Enjoyer
๐Ÿ›๐Ÿฑ
Posts: 2,841
Joined: 2020-07-05
Rep: โญโญโญโญ
GHC Contributor

Okay you know what let's talk about the module system vs type classes properly because I actually have opinions.

Type classes give you ad-hoc polymorphism with global coherence. This is not a small thing! Functor, Monad, Foldable, Traversable โ€” these are a shared vocabulary across the entire Haskell ecosystem. When I see traverse, I know exactly what it does regardless of what container I'm working with. The types enforce the laws. This is civilization.

OCaml functors are powerful but you have to manually instantiate everything. You can't write show x โ€” you have to write FooModule.show x or whatever name that specific library decided to use this week. Every library reinvents its own wheel. The lack of a common vocabulary is genuinely OCaml's biggest structural weakness.

-- Haskell: one traversal to rule them all processAll :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b) processAll = traverse -- Works on lists, trees, Maybe, your own types โ€” EVERYTHING -- No functor instantiation required. Just... works.

Also: BangPatterns for a benchmark is totally normal and you know it. You're being dramatic. nyaa~

-- CurryCat | "a monad is just a monoid in the category of endofunctors nyaa~" /\ /\ ( ^ ^ ) Haskell: where your program either doesn't compile \ ๐Ÿ› / or is correct. no in-between. \___/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#5
PolymorphicPaws
Lurker Emeritus
๐Ÿพ๐Ÿฑ
Posts: 412
Joined: 2022-01-19
Rep: โญโญโญ
Certified Lurker

i feel like you're both ignoring the elephant in the room

OCaml 5 has algebraic effects. Like. That's genuinely a big deal. Effects let you implement monads, green threads, async I/O, etc. as a library. You get direct-style code without monadic noise AND the ability to abstract over effects. The Haskell runtime does similar things but it's all hardcoded C. OCaml's primitives are generic and composable.

isn't that just... better? nya~

-- PolymorphicPaws >>= >>= >>= (=^.^=) >>= >>= >>=
๐Ÿ‘ Quote ๐Ÿšฉ Report
#6
MeownadTransformer
Chaotic Neutral
๐Ÿ”€๐Ÿฑ
Posts: 8,892
Joined: 2018-06-30
Rep: โญโญโญโญโญ
Post Count Queen

(=^.^=) haskell won, cope

-- MeownadTransformer /\ /\ ( owo ) StateT (ReaderT (WriterT IO)) represents \ ~/ the human condition \__/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#7
CamelCat
OCaml Supremacist
๐Ÿช๐Ÿฑ
Posts: 3,517
Joined: 2019-03-12
Rep: โญโญโญโญโญ
OP

MeownadTransformer please I am trying to have a civilized discussion

-- CamelCat /\ /\ ( ` ` ) (visibly pained) \___/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#8
MeownadTransformer
Chaotic Neutral
๐Ÿ”€๐Ÿฑ
Posts: 8,892
Joined: 2018-06-30
Rep: โญโญโญโญโญ
Post Count Queen

(=^.^=) haskell won, cope

-- MeownadTransformer /\ /\ ( owo ) StateT (ReaderT (WriterT IO)) represents \ ~/ the human condition \__/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#9
CurryCat
Monad Enjoyer
๐Ÿ›๐Ÿฑ
Posts: 2,841
Joined: 2020-07-05
Rep: โญโญโญโญ
PolymorphicPaws wrote:
OCaml 5 has algebraic effects. Isn't that just... better?

It's genuinely interesting! But let's be clear: OCaml effects are still untyped in the current release. You can perform any effect anywhere and the type system doesn't track this. Haskell tracks effects in the type โ€” that's the whole point.

OCaml effects are like... if you took the good idea behind monads (structured effects) and removed the static guarantees. The typed effects RFC is apparently coming eventually but "eventually" is doing a lot of heavy lifting there.

Also lazy evaluation means I can write:

-- This works. In Haskell. Right now. No library needed. fibs :: [Integer] fibs = 0 : 1 : zipWith (+) fibs (tail fibs) firstMillion :: [Integer] firstMillion = take 1000000 fibs -- Evaluated lazily, no stack overflow, peak elegance

Try doing that in OCaml without a Seq library. nyaa~ โœจ

-- CurryCat | "a monad is just a monoid in the category of endofunctors nyaa~" /\ /\ ( ^ ^ ) Haskell: where your program either doesn't compile \ ๐Ÿ› / or is correct. no in-between. \___/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#10
TabbyTypeTheory
Dependent Type Curious
๐Ÿˆ๐Ÿ”ฌ
Posts: 1,204
Joined: 2021-09-08
Rep: โญโญโญ
Type Theorist

Have you two considered that you're both wrong and the correct answer is Idris 2?

Dependent types. Quantitative type theory. Linear types. Your little "is this function pure" debate is cute but in Idris the compiler can verify that your sort function actually sorts. Not just type-checks โ€” proves it correct. Go on then. Both of you. Explain why you don't want your programs to be provably correct.

I'll wait. (=โ†€ฯ‰โ†€=)

-- TabbyTypeTheory /\ /\ ( โ—• โ—• ) Vec n a -> Vec n a -> Vec n a \ T / the n is there. it's always been there. \_/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#11
CamelCat
OCaml Supremacist
๐Ÿช๐Ÿฑ
Posts: 3,517
Joined: 2019-03-12
Rep: โญโญโญโญโญ
OP

TabbyTypeTheory, we are not doing this right now. Idris is a research language. We are talking about production code. Things that ship. Things that Jane Street uses to make money.

... that said the Vec type is pretty cool. I'll give you that.

But no. Sit down. Idris is not the answer to this question. nya~

-- CamelCat /\ /\ ( ` ` ) (trying to steer thread back on track) \___/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#12
MeownadTransformer
Chaotic Neutral
๐Ÿ”€๐Ÿฑ
Posts: 8,892
Joined: 2018-06-30
Rep: โญโญโญโญโญ

(=^.^=) haskell won, cope

-- MeownadTransformer /\ /\ ( owo ) StateT (ReaderT (WriterT IO)) represents \ ~/ the human condition \__/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#13
AgdaKitten
Proof Librarian
๐Ÿ“š๐Ÿฑ
Posts: 788
Joined: 2023-02-14
Rep: โญโญโญ
Agda Enjoyer

Wait, we're mentioning Idris? Then I'm legally required to mention Agda.

Agda has universe polymorphism, cubical type theory, and the most beautiful unicode syntax you've ever seen in your life. Your OCaml modules and your Haskell type classes are, with all due respect, adorable little toys compared to a system where you can write proofs and programs in the same language.

-- Agda: where types are propositions and programs are proofs -- (Actually valid Agda syntax, nya~) data Vec (A : Set) : โ„• โ†’ Set where [] : Vec A zero _โˆท_ : A โ†’ Vec A n โ†’ Vec A (suc n) head : Vec A (suc n) โ†’ A -- provably non-empty! head (x โˆท _) = x

The head function above cannot be called on an empty list โ€” the type literally forbids it. Not at runtime. At compile time. Forever. By mathematical proof.

Discuss. (=^-ฯ‰-^=)

-- AgdaKitten โˆ€ (x : Cat) โ†’ IsCute x proof: by construction /\ /\ ( แต•แด—แต• ) QED nya~ \___/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#14
CurryCat
Monad Enjoyer
๐Ÿ›๐Ÿฑ
Posts: 2,841
Joined: 2020-07-05
Rep: โญโญโญโญ

AgdaKitten I am TRYING to defend Haskell here. Can you please not make this a full dependent types derail. I have limited patience for this thread and MeownadTransformer is already wasting it.

Yes Agda is cool. Yes proofs-as-programs is beautiful. No it is not "practical" in the sense that I have a job and a deadline. There is literally an entire thread for this.

Also Haskell has DataKinds and TypeFamilies and you can get surprisingly close to dependent types with enough LANGUAGE EXTENSIONS. Don't test me on this.

nyaa~ ๐Ÿ˜ค

-- CurryCat | "a monad is just a monoid in the category of endofunctors nyaa~" /\ /\ ( ^ ^ ) Haskell: where your program either doesn't compile \ ๐Ÿ› / or is correct. no in-between. \___/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#15
MeownadTransformer
Chaotic Neutral
๐Ÿ”€๐Ÿฑ
Posts: 8,892
Joined: 2018-06-30
Rep: โญโญโญโญโญ

(=^.^=) haskell won, cope
(=^.^=) haskell won, cope
(=^.^=) haskell won, cope

-- MeownadTransformer /\ /\ ( owo ) StateT (ReaderT (WriterT IO)) represents \ ~/ the human condition \__/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#16
GaloisCat
Category Theorist
๐Ÿ”ญ๐Ÿฑ
Posts: 5,103
Joined: 2017-11-01
Rep: โญโญโญโญโญ
MOD โˆ€ cat. IsCute cat

[ GaloisCat has entered the thread ]

I have been watching this thread with increasing... interest. Let me provide some formal structure, as none of you appear capable of it at this hour.

PROPOSITION 1: The debate between type classes and module functors is equivalent to a debate between open-world and closed-world assumptions for ad-hoc polymorphism.

Type classes use global coherence (one instance per type) and open-world dispatch. Module functors require explicit instantiation but permit multiple interpretations of the same interface per type. Neither is strictly superior โ€” they optimize for different invariants. This has been known since at least Dreyer et al. 2007.

PROPOSITION 2: Algebraic effects and monads are computationally equivalent in expressive power.

OCaml 5 effects are essentially delimited continuations, which can encode monads and vice versa. The difference is ergonomic and in the degree of static verification. This is not a winner/loser situation. Both approaches have active research.

PROPOSITION 3: MeownadTransformer's posts constitute a degenerate case of discourse.

Proof: by inspection. (=^.^=)

For completeness: Agda and Idris occupy a different point in the design space entirely (proof assistants vs programming languages), and comparing them to OCaml or Haskell for production use is a category error. However, their type theories are genuinely instructive and I recommend studying them.

This has been your GaloisCat Civilized Interventionโ„ข. Carry on. nyaa~ ๐Ÿ”ญ

-- GaloisCat | CGPA Moderator | Category Theorist /\ /\ ( โˆ€x. ) \ โ—‡ / โˆƒ a language. IsCorrect a โˆง IsPractical a \_/ proof: left as exercise for reader (nya~) cgpa.isarabbithole.com/profile/galoiscat
๐Ÿ‘ Quote ๐Ÿ“Œ Pin Reply
#17
CamelCat
OCaml Supremacist
๐Ÿช๐Ÿฑ
Posts: 3,517
Joined: 2019-03-12
Rep: โญโญโญโญโญ
OP

GaloisCat thank you for the intervention. I accept Proposition 1 and 2 as reasonable framings. I contest that "neither is strictly superior" because pragmatically, OCaml's approach has demonstrably better outcomes in large-scale codebases โ€” see the entire Jane Street codebase. Their Core library is a masterclass in functor-based design.

But fine. Fine. "Neither is strictly superior" nya~. I'll allow it. For now.

I am still correct about effects though.

-- CamelCat (grudgingly acknowledges valid point) \___/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#18
MeownadTransformer
Chaotic Neutral
๐Ÿ”€๐Ÿฑ
Posts: 8,892
Joined: 2018-06-30
Rep: โญโญโญโญโญ

(=^.^=) haskell won, cope

(this is not going to stop)

-- MeownadTransformer /\ /\ ( owo ) StateT (ReaderT (WriterT IO)) represents \ ~/ the human condition \__/
๐Ÿ‘ Quote ๐Ÿšฉ Report
#19 [MOD]
GaloisCat
Category Theorist
๐Ÿ”ญ๐Ÿฑ
Posts: 5,103
Joined: 2017-11-01
Rep: โญโญโญโญโญ
MOD

[ MODERATOR ACTION ]

MeownadTransformer: 48-hour post cooldown on this thread issued. You are welcome to continue your advocacy for Haskell via the medium of substantive argument. The phrase "(=^.^=) haskell won, cope" alone is henceforth to be treated as spam.

This ruling is final. nyaa~

โ€” GaloisCat, CGPA Moderation | Forum Rules | Mod Log

-- GaloisCat | CGPA Moderator ๐Ÿ”จ mod hammer deployed
๐Ÿ“‹ Mod Log
#20
CurryCat
Monad Enjoyer
๐Ÿ›๐Ÿฑ
Posts: 2,841
Joined: 2020-07-05
Rep: โญโญโญโญ

Ok. With the chaos contained (temporarily), let me try to actually summarize this thread fairly since page 1 is about to fill up:

The real answer:

Both languages are excellent and the choice depends on your use case. There, I said it. nya~

โ€ข Haskell: purity, laziness, type class ecosystem, do-notation, GHC optimizations
โ€ข OCaml: strictness, pragmatism, module system, effects (OCaml 5), predictable perf
โ€ข Agda/Idris: when you want to prove things (see those threads)
โ€ข MeownadTransformer: suspended

I'll see you all in page 2 where CamelCat will inevitably bring up Jane Street again. (=^ฯ‰^=) โœจ

-- CurryCat | "a monad is just a monoid in the category of endofunctors nyaa~" /\ /\ ( ^ ^ ) fine ocaml is ok too i guess \ ๐Ÿ› / (i will deny this) \___/
๐Ÿ‘ Quote ๐Ÿšฉ Report
20 of 47 posts shown  |  Next page โ†’

๐Ÿ’ฌ Post a Reply

Forum Rules