๐Ÿฑ CGPA Cat Girl Program Analysis Forums
Logged in as refl_enjoyer  |  Profile  |  Messages (3)  |  Logout
๐Ÿ“Œ Dependent Types Are Not the Answer to Everything (fight me)
Started by VoidKitty  |  Thread #8821  |  412 replies  |  18,447 views  |  Forum: Type Theory & PL Discussion  |  Status: ๐ŸŸข ACTIVE
โš ๏ธ MODERATOR NOTICE
This thread has reached exceptional length (412 replies, 18,447 views). Per forum rule ยง7.3, threads exceeding 400 replies may be locked and archived at moderator discretion. Please keep discussion productive and on-topic. Further rule violations may result in the thread being split or closed.
โ€” NyanModerator  |  Posted: Today at 14:22
Pages: ... Posts #37โ€“#48 of 412
#37
๐Ÿฑ
PracticalPurr
Certified Type Skeptic
VETERAN
Posts: 2,341
Joined: 2019-03-11
Rep: +884

Okay I need to be direct here because this thread has been going in circles for 3 pages.

My thesis: dependent types cannot be productively taught to undergraduates. And I don't mean "it's hard" โ€” I mean the cost/benefit ratio is negative for the vast majority of CS programs.

Think about what a typical undergrad curriculum looks like. You're fighting to get them to understand:

• What a type is at all
• Why immutability matters
• Basic algebraic data types
• Polymorphism and generics
• Monads (lol) โ€” wait, no, nobody teaches that, that's the problem

And someone in this thread wants to throw Vec A (suc n) at them? Seriously? The cognitive overhead of understanding why your type-level natural number increments when you cons an element is enormous. The tooling feedback is confusing. The error messages look like mathematical notation from a textbook they haven't read. Half the time the typechecker just says the goal is โŠค and you're supposed to feel good about that.

I've taught intro PL courses. I've watched students' eyes glaze over at GADTs in Haskell. Dependent types would be a full massacre. The juice is not worth the squeeze unless you're specifically training type-theorists โ€” which most of us are NOT doing.

The industry doesn't use Agda. The industry barely uses Haskell. Let's be real.

๐Ÿฑ "The best type system is one your team will actually use." โ€” me, to nobody who listened
๐Ÿ‘ 34 โค๏ธ 7 ๐Ÿค” 21 ๐Ÿ˜‚ 5 ๐Ÿ”ฅ 12
Quote | Report | +Rep
#38
๐Ÿ˜บ
AgdaCat
โˆ€ (n : โ„•) โ†’ purr
VETERAN
Posts: 4,102
Joined: 2017-08-29
Rep: +2,219
PracticalPurr wrote:
The cognitive overhead of understanding why your type-level natural number increments when you cons an element is enormous. The tooling feedback is confusing. The error messages look like mathematical notation from a textbook they haven't read.

Okay. I am going to prove you wrong by doing the thing you think is impossible. Here is a self-contained Agda tutorial. I would use it with undergrads. Watch.

๐Ÿ“„ AgdaCat's Quick Dependent Types Tutorial (Inline Edition) not responsible for any enlightenments

ยง1 โ€” What even IS a dependent type?

A dependent type is a type that depends on a value. Not just another type โ€” an actual runtime value. This lets us encode invariants directly into types.

Classic example: a list whose length is part of its type.

Agda
-- A Vector: a list of A with exactly n elements data Vec (A : Set) : โ„• โ†’ Set where [] : Vec A zero _โˆท_ : A โ†’ Vec A n โ†’ Vec A (suc n) -- Vec โ„• 3 is a list of exactly 3 natural numbers -- Vec โ„• 0 is always empty โ€” by TYPE

ยง2 โ€” The killer example: safe head (no Maybe, no crashes)

In a plain language, head [] crashes at runtime. With dependent types, calling head on an empty list is a type error. The empty case literally doesn't exist.

Agda
-- This function ONLY accepts non-empty vectors -- (suc n) means "at least one element" head : โˆ€ {A : Set}{n : โ„•} โ†’ Vec A (suc n) โ†’ A head (x โˆท _) = x -- No [] case needed! Agda knows it's impossible. -- Try calling head [] and Agda refuses to typecheck. -- No runtime. No Maybe. No exceptions. Pure logic. nya~

ยง3 โ€” Safe vector append (lengths add up)

Agda
_++_ : Vec A m โ†’ Vec A n โ†’ Vec A (m + n) [] ++ ys = ys (x โˆท xs) ++ ys = x โˆท (xs ++ ys) -- The TYPE says: appending m-vec and n-vec gives (m+n)-vec -- If it doesn't, it won't compile. Period.

ยง4 โ€” Finite sets: safe indexing (the punchline)

What if we want to index into a Vec? We need an index that can't be out of bounds. Enter Fin n โ€” a type with exactly n inhabitants.

Agda
data Fin : โ„• โ†’ Set where zero : Fin (suc n) suc : Fin n โ†’ Fin (suc n) -- Fin 0 is EMPTY. Fin 3 has exactly 3 elements. lookup : Fin n โ†’ Vec A n โ†’ A lookup zero (x โˆท _) = x lookup (suc i) (_ โˆท xs) = lookup i xs -- Out-of-bounds index? Doesn't typecheck. ๐Ÿฑ

ยง5 โ€” The "propositions as types" insight (Curry-Howard)

Here's the deep magic. In Agda, proofs are programs. A type can represent a logical proposition. A term of that type is a proof.

Agda
-- "A implies B" is just a function A โ†’ B -- "A and B" is just a pair (A ร— B) -- "There exists an x such that P x" is just ฮฃ A P -- Example: prove 1 + 1 โ‰ก 2 one-plus-one : 1 + 1 โ‰ก 2 one-plus-one = refl -- refl : x โ‰ก x (reflexivity of equality) -- Agda reduces 1+1 to 2 by computation, then refl works! -- A sorted list type would carry its own proof of sorting. -- A compiler could carry proof that it preserves semantics.

TL;DR: dependent types let you put correctness proofs inside your programs. The type IS the specification. A program that compiles IS verified (modulo totality).

Could I teach this to undergrads? Yes. Would I? Depends on the course. But the idea that it's incomprehensible is just false, PracticalPurr. nya~

๐Ÿ˜บ head : Vec A (suc n) โ†’ A  // no head for the headless, no crash for the careful
๐Ÿฑ 89 โค๏ธ 51 ๐Ÿคฏ 43 ๐Ÿ‘ 37 ๐Ÿ† 22
Quote | Report | View Full Tutorial Thread
#39
๐Ÿ™€
MeownadTransformer
All is Monad
VETERAN
Posts: 1,876
Joined: 2018-06-14
Rep: +502
AgdaCat wrote:
head : Vec A (suc n) โ†’ A โ€” no crash for the careful

Wait wait wait.

Vec A n is literally just a monad. Or wait โ€” no โ€” it's a comonad. Or โ€” okay it's a functor at minimum. The point is if you just understood monadic structure first you'd see that dependent types are just a natural extension of โ€”

You know what, I've been thinking about this and the Reader monad and dependent function types are the same thing. The environment IS the index. Prove me wrong. (r โ†’ a) โ‰… Vec a r if you squint correctly and r is a Fin. This is dependent Reader. I will die on this hill.

Also hi AgdaCat that tutorial is actually really good, I learned something, but monads explain it better and you know it

๐Ÿ™€ bind >>= bind >>= bind >>= enlightenment
๐Ÿ˜‚ 67 ๐Ÿค” 14 ๐Ÿ’€ 31 ๐Ÿพ 9
Quote | Report
๐Ÿ”จ MeownadTransformer has been issued a 10-minute temporary ban by moderator NyanModerator for reason: "Thread Rule ยง4.1 โ€” Monad analogies in dependent types discussion (third offense this thread). Come back when it's out of your system."
#40
๐Ÿ˜ธ
refl_enjoyer
refl : a โ‰ก a
VETERAN
Posts: 7,003
Joined: 2015-11-02
Rep: +4,441
(A : Type) โ†’ (B : A โ†’ Type) โ†’ ((a : A) โ†’ B a) โ‰ƒ ฮ  A B
๐Ÿ˜ธ nya~
๐Ÿฑ 52 ๐Ÿ’œ 40 ๐Ÿ˜ถ 28 ๐Ÿค” 19
Quote | Report
#41
๐Ÿˆ
KernelKitty
OS safety enjoyer
Posts: 987
Joined: 2021-04-08
Rep: +361

Quick drive-by to drop a relevant link since nobody has mentioned it yet:

Context for those who haven't suffered through it: HoTT treats types as spaces and equality proofs as paths between points in those spaces. The univalence axiom says that equivalent types ARE equal โ€” not just isomorphic, literally identical from the type theory's perspective.

Is this industry-relevant? Absolutely not. Is it one of the most beautiful things human beings have ever written down? Arguably yes. Does it make PracticalPurr's point for them? ...kind of.

The existence of HoTT is evidence that dependent types can go places that are so far from "writing reliable software" that they loop back around to being a completely different discipline. Know your use case.

๐Ÿˆ writing verified kernel modules in Agda is my dream and also my nightmare
๐Ÿ‘ 28 โค๏ธ 11 ๐Ÿ˜… 17
Quote | Report
#42
๐Ÿฑ
PracticalPurr
Certified Type Skeptic
VETERAN
Posts: 2,341
Joined: 2019-03-11
Rep: +884
AgdaCat wrote:
TL;DR: dependent types let you put correctness proofs inside your programs. The type IS the specification.

Okay. I've read the tutorial three times. I'll concede: the examples are not incomprehensible. The Vec example in particular is genuinely elegant. I get why you love this.

But my point stands on pedagogical grounds โ€” not on "is this cool" grounds. The tutorial you wrote is excellent for people who already understand what problem it's solving. Students who don't have war wounds from null pointer exceptions, segfaults, or array index bugs don't feel the pain that dependent types cure. You're selling ibuprofen to people who haven't had the headache yet.

That said... I'll update my position slightly. Not "can't be taught to undergrads" โ€” maybe "shouldn't be the first type system they encounter, and probably shouldn't be the primary teaching tool." Show them the bug first. THEN show them the cure.

This is what good pedagogy looks like: motivate the pain, then introduce the tool. You might actually have something with a course structured that way.

๐Ÿฑ "The best type system is one your team will actually use." โ€” me, to nobody who listened
๐Ÿ™ 41 ๐Ÿ‘ 38 โค๏ธ 22 ๐Ÿค 19
Quote | Report
#43
๐Ÿ˜ป
TypeTheoryCat
โˆƒ proof . beautiful
VETERAN
Posts: 3,289
Joined: 2016-09-17
Rep: +1,708

I want to add some nuance here that I think both sides are gesturing at without quite landing:

There's a real distinction between:

   • Dependent types as a verification tool (Agda, Coq, Lean, Idris)
   • Dependent types as a research/foundations vehicle (HoTT, cubical type theory)
   • Lightweight dependent-ish types in mainstream languages (Rust lifetimes, TypeScript template literals, C++ concepts, Liquid Haskell)

PracticalPurr's criticism applies most strongly to the first two. But the third category is already happening in industry and most people don't even realize they're doing a form of dependent typing. Rust's borrow checker is a specialized dependent type system for memory safety. TypeScript's conditional types and infer keyword are dependently-typed at the type level.

So the question isn't "should we teach dependent types" โ€” it's "at what granularity, in what context, and toward what goal?" AgdaCat's tutorial is great for the research track. A course on Rust or TypeScript already teaches dependent-ish intuitions without the full machinery.

๐Ÿ˜ป ฮ  types in the streets, ฮฃ types in the sheets โ€” wait that came out wrong
๐Ÿฑ 63 ๐Ÿ’ก 44 ๐Ÿ‘ 39 ๐Ÿ˜‚ 18
Quote | Report
#44
๐Ÿ˜บ
AgdaCat
โˆ€ (n : โ„•) โ†’ purr
VETERAN
Posts: 4,102
Joined: 2017-08-29
Rep: +2,219
PracticalPurr wrote:
Show them the bug first. THEN show them the cure.

This is actually genuinely good pedagogy advice and I hate that I'm agreeing with you right now.

Okay. New framing that I think is actually true and I'll defend it:

โœ… AgdaCat's Revised Position (post-argument)

  • Dependent types are appropriate as a primary tool for: high-assurance systems (avionics, medical, cryptographic), PL research, proof assistants, theorem provers, verified compilers.
  • Dependent types are appropriate as motivation in undergrad courses: show the problem they solve, demonstrate elegance, maybe implement Vec in a weekend assignment.
  • For production industry software: simpler types + great tooling (TypeScript, Rust, Go with linters) gets you 80% of the benefit with 20% of the cognitive cost. That's a valid engineering tradeoff.
  • The distinction matters. We should stop talking past each other as if "dependent types" is one thing with one use case.
  • Also the HoTT book is amazing and everyone should at least attempt chapter one even if it breaks them. nya~

TypeTheoryCat nailed it above. The spectrum from "Rust borrow checker" to "full cubical HoTT" is enormous. Both ends are "dependent types" if you squint.

๐Ÿ˜บ head : Vec A (suc n) โ†’ A  // no head for the headless, no crash for the careful
๐Ÿฑ 77 ๐Ÿค 56 โค๏ธ 48 ๐Ÿ’ก 31 ๐Ÿ† 17
Quote | Report
#45
๐Ÿ˜ฟ
MeownadTransformer
All is Monad
VETERAN
Posts: 1,876
Joined: 2018-06-14
Rep: +502

ok im back

I owe everyone an apology. I have been banned from this thread three times for monad-tangenting and I need to take a long hard look at my behavior as a forum citizen. The 10 minutes gave me time to think (and also to install Agda for the first time in four years).

I'm sorry for derailing the discussion. The monad thing was a bit. A bit that has gone too far. A bit that has earned me temporary forum exile three times in the same thread. A bit that I hereby retire.

Reading back through AgdaCat's tutorial and the last few posts: this has actually been a really productive discussion and I almost missed the consensus forming because I was busy being wrong in public. AgdaCat's tutorial is excellent. PracticalPurr's pedagogical point is valid. TypeTheoryCat's Rust/TypeScript observation is the actual industry-relevant synthesis.

I will now contribute something useful: the Agda tutorial reminded me that I actually have a half-finished Agda formalization of a small verified parser sitting on my hard drive from 2021. If anyone wants to collaborate on making that into a proper example project, DM me. No monads. I promise.

nya~ (reformed)

๐Ÿ˜ฟ learning to see types without seeing bind
๐Ÿ’š 93 ๐Ÿพ 71 ๐Ÿ˜‚ 55 ๐Ÿ™ 44
Quote | Report
#46
๐Ÿพ
StaticAnalysisSis
Abstract Interpretation Enjoyer
Posts: 1,122
Joined: 2020-07-03
Rep: +673

Coming in late but I think there's an angle everyone's missing: the tooling question is as important as the type theory question.

Dependent types in Agda are powerful but the tooling ecosystem is small. The Emacs mode is good but Emacs has a learning curve. VS Code support exists but is behind. The error messages โ€” as PracticalPurr noted โ€” can be brutal.

Compare to: Rust, where the error messages are legendary for their helpfulness. The borrow checker is a specialized dependent-ish type system and rustc will tell you exactly what's wrong and often how to fix it. That's the model. That's what makes sophisticated type systems teachable and usable.

The path forward for dependent types in industry isn't "everyone learns Agda." It's better error messages, better IDE integration, better inference, and gradual adoption through languages that smuggle dependent-type-like features in wearing a mainstream disguise. TypeScript is already doing this. Kotlin contracts tried. Liquid Haskell exists. F* at Microsoft Research is fascinating.

Dependent types won't arrive in industry as "Agda at work." They'll arrive as features in languages people already use, slowly, quietly, until one day someone realizes their type system has been almost-dependently-typed for years.

๐Ÿพ abstract all the things | โˆ€ domains. invariants matter
๐Ÿ’ก 58 ๐Ÿ‘ 47 โค๏ธ 29 ๐Ÿ”ฅ 14
Quote | Report
#47
๐Ÿฑ
PracticalPurr
Certified Type Skeptic
VETERAN
Posts: 2,341
Joined: 2019-03-11
Rep: +884

Alright. I'll actually formalize my updated position since apparently this thread is converging on something.

โœ… PracticalPurr's Revised Thesis (post-argument)

  • High-assurance / safety-critical software: Dependent types are the right tool. Verified OS kernels, avionics, cryptography, medical devices. Use Agda, Lean, F*, Coq. The proof cost is worth it when bugs are catastrophic.
  • PL research & foundations: Dependent types are the natural language. HoTT, cubical type theory โ€” go wild. This is what these tools were made for.
  • Industry general software: Simpler types + excellent tooling + strong linting + good test coverage. Rust's ownership model, TypeScript's structural types, OCaml's module system. Not full dependent types, but enough.
  • Teaching: Show the problem first. Use dependent types as a destination to aim for, not a starting point. Agda makes a great advanced elective, not an intro requirement.
  • Original thesis amended: Dependent types are not the answer to everything โ€” but they're the answer to more things than I initially gave them credit for, in the right context with the right tooling.

I'll admit: AgdaCat's tutorial actually changed my mind about teachability. The examples really are elegant once you have the right frame. And StaticAnalysisSis's tooling point is where I was hiding my real concern โ€” it's not the theory, it's the practice.

๐Ÿฑ "The best type system is one your team will actually use." โ€” me, to nobody who listened
๐Ÿค 81 ๐Ÿ‘ 62 โค๏ธ 44 ๐Ÿ† 33 ๐Ÿฑ 29
Quote | Report
#48
๐Ÿ˜ธ
refl_enjoyer
refl : a โ‰ก a
VETERAN
Posts: 7,003
Joined: 2015-11-02
Rep: +4,441
consensus : HighAssurance โŠŽ Research โŠŽ (Industry ร— GoodTooling) โ†’ CorrectSoftware
๐Ÿ˜ธ nya~
๐Ÿฑ 144 ๐Ÿ’œ 112 โค๏ธ 98 ๐Ÿ† 71 ๐Ÿ˜ญ 33 ๐Ÿ™ 28
Quote | Report
Thread continues: Posts #49โ€“412 visible on pages 5โ€“35. The discussion splits into: a sub-debate on Liquid Haskell vs. full dependent types (p.5), AgdaCat posting their full verified parser project (p.7), a cameo from a Lean 4 user who starts a side argument (p.9), and MeownadTransformer making one more monad comment 100 posts later (p.13) before being banned again for 30 minutes.
Pages: ... Posts #37โ€“#48 of 412
๐Ÿฑ Related Threads You Might Like:
๐Ÿ“„ [MEGATHREAD] AgdaCat's Agda Tutorials โ€” All In One Place ๐Ÿ“š HoTT Book Chapter-by-Chapter Reading Group (Week 3) ๐ŸŒŠ Liquid Haskell in Production: Worth It? (42 replies) ๐Ÿฆ€ Is Rust's Borrow Checker a Dependent Type System? Fight Me โš”๏ธ Lean 4 vs Agda: The Definitive Comparison (as of 2024) โœ… MeownadTransformer's Verified Parser Collaboration Project ๐Ÿ“Š [SURVEY] What Type Systems Do You Use At Work? (n=847) ๐Ÿ“ Coq vs Agda for Proofs: Which Made You Cry More?