Learn Next — Cross-Language Recommendation Graph
Learn Next — Cross-Language Recommendation Graph
- Type: cross-cutting recommendation graph
- Languages covered: 51 (see _index)
- Last updated: 2026-05-07
TL;DR
- “What should I learn next?” is two questions hiding as one: lateral (a similar language for breadth, employability, or domain expansion) vs depth (a paradigm-shifter that rewires how you think).
- Most engineers benefit more from one well-chosen depth-shift (Lisp, Haskell, or Rust) than from learning ten lateral cousins.
- The strongest “second language” picks for an X-only developer in 2026 are usually Rust (paradigm shift to ownership) and TypeScript (employability + types).
- This is opinionated. The recommendations come from common community paths, university curricula, and the patterns that recur across the 51 individual language notes.
How to use this guide
For each source language, you’ll find 3-5 recommended “next languages” with rationale tagged:
- (lateral) — similar feel, expands breadth/skills/employability. Low surprise, modest payoff.
- (depth) — different paradigm; the goal is to rewire how you think. High surprise, large payoff.
- (domain) — same paradigm, different application area (web → systems, data → ML, etc.).
- (employability) — the recommendation is mostly about the job market.
Each entry follows: → Target (tag, axis): Rationale. Be ruthless if a recommendation doesn’t apply to your goals — they all assume you want to grow as a generalist.
The bridges — by source language
From Python
- → Rust (depth, systems): Trade GC + duck typing for ownership + types. Best second language for a Python-only dev who wants performance literacy. PyO3 lets you incrementally rewrite hot paths.
- → Julia (domain, numeric): If your Python is mostly numpy/pandas/scipy, Julia gives you one language for the whole stack with native multiple dispatch. Speed without C extensions.
- → TypeScript (lateral, full-stack): Closest dynamic-with-types ergonomic match for going web/full-stack. TS’s structural types are the closest cousin to Python’s duck typing.
- → Haskell (depth, FP): To deeply learn types and pure FP. Not a job move; a brain move. Pairs well with mypy-disciplined Python afterward.
- → Clojure (depth, FP-on-JVM): If you want FP without giving up the JVM ecosystem; the Lisp epiphany alongside it.
From JavaScript
- → TypeScript (lateral, types): Non-negotiable for any serious JS career in 2026.
- → Rust (depth, systems): The “where my code goes when I want to leave Node” pick. Cargo will feel familiar after npm.
- → Elixir (depth, actors): If you do real-time / streaming web (Phoenix LiveView is the killer app). Trade Node’s single-threaded event loop for BEAM’s millions of processes.
- → Go (lateral, services): For backend microservices; less surface area than Java/Kotlin, more performance than Node.
From TypeScript
- → Rust (depth, systems): The natural progression — TS already taught you that types are good; Rust shows you what types can prevent.
- → Haskell (depth, type theory): Learn what TS’s type system is trying to be. Conditional + mapped types ≈ type families; you’ll suddenly understand TS deeper.
- → Scala (lateral, advanced types on JVM): Match types in Scala 3 are TS’s conditional types with tighter semantics.
- → Elm (not in 51) or Gleam (lateral, FP web): Sound type systems for the web frontend.
From Java
- → Kotlin (lateral, JVM modernization): Drop-in better Java. Null safety, data classes, coroutines.
- → Scala (depth, FP-on-JVM): To learn typed FP without leaving the JVM. Cats Effect and ZIO are the modern entry points.
- → Rust (depth, systems + ownership): For the engineer who wants to understand memory and zero-cost abstraction.
- → Clojure (depth, Lisp-on-JVM): The Lisp epiphany without leaving Maven/Gradle.
- → Go (lateral, services): Less ceremony for backend services.
From C
- → Rust (depth, systems with safety): The conventional next step. Ownership + lifetimes + traits = C’s power with compile-time safety.
- → Zig (lateral, simpler systems): Closer to C’s mental model. Comptime instead of macros.
zig cceven compiles your existing C. - → C++ (lateral, depth-extension): If your job demands it. Templates + RAII + standard library. Avoid until you’ve seen Rust to know what you’re trading.
- → Odin (lateral, modern simplicity): Zig-adjacent; allocator-as-context; small but capable.
From C++
- → Rust (depth, ownership at compile time): Most C++ idioms have a checked Rust equivalent. RAII becomes Drop; smart pointers become Box/Rc/Arc.
- → Zig (lateral, simpler systems): Refresh your mental model with a simpler-on-purpose language.
- → Swift (lateral, OO-with-modern-types): For Apple platforms or when you want C++ ergonomics + ARC. C++ interop is now first-class in Swift.
- → D (not in 51) (lateral): If you want C++ with a saner module system.
From [[Languages/csharp|C#]]
- → [[Languages/fsharp|F#]] (depth, FP-on-.NET): The natural FP companion. Same runtime; different paradigm. Type providers are unique.
- → Rust (depth, systems): For when GC and reflection get in your way.
- → TypeScript (lateral, types-elsewhere): The structural-types cousin; serves you on the frontend.
- → Swift (lateral, similar OO + modern types): If you go cross-platform mobile.
From Go
- → Rust (depth, types + ownership): What Go users reach for when they want enums + traits + ownership and accept the learning cliff.
- → Elixir (depth, actors + supervision): Different concurrency model; same “build resilient distributed systems” goal. Phoenix LiveView is a revelation.
- → Zig (lateral, manual control): For when you want Go’s simplicity but down a level.
- → Python + ML (domain): If your Go services consume ML models, learning the upstream language helps.
From Rust
- → Haskell (depth, types as paradigm): Rust’s traits + lifetimes are baby Haskell type classes + linearity. Going to the source completes the journey.
- → Zig (lateral, simpler systems): When Rust’s complexity feels excessive for the problem. Different point on the safety/simplicity Pareto curve.
- → OCaml (lateral, ML family): The historic family Rust derives much from. The Rust compiler was originally written in OCaml.
- → Idris (depth, dependent types): If you wanted MORE types, Idris 2 gives you values in types and quantitative type theory.
- → Elixir (lateral, distribution): For the part of “systems” Rust doesn’t address — fault-tolerant distributed systems.
From Swift
- → Rust (depth, ownership): Similar surface (struct + protocol/trait, generics) but checked at compile time, no ARC.
- → Kotlin (lateral, mobile): For Android. Coroutines vs structured concurrency.
- → TypeScript (lateral, frontend): If you’re building React Native; TS is the shared lingua franca.
From Kotlin
- → Swift (lateral, iOS): The natural cross-platform mobile pair.
- → Scala (depth, FP-on-JVM): Kotlin without the timidity. Especially Scala 3.
- → Rust (depth, systems): For when GC and JVM startup time matter.
- → Elixir (depth, actors): If your Kotlin is mostly Spring + microservices, Elixir is the architectural eye-opener.
From Ruby
- → Elixir (depth, actors + Phoenix): Created by ex-Ruby community member José Valim; Phoenix is “what Rails would be if you started over with concurrency in mind”.
- → Crystal (lateral, “compiled Ruby”): Same syntax flavor, native code, types.
- → Rust (depth, systems): For when Rails performance bites.
- → TypeScript (lateral, full-stack): For frontend convergence.
From PHP
- → TypeScript (lateral, full-stack): The natural backend-to-frontend bridge.
- → Go (lateral, performance services): For high-throughput services.
- → Rust (depth, types + memory): Big jump; high payoff.
- → Elixir (depth, actors): If you do real-time PHP (you probably don’t, and that’s the lesson).
From Scala
- → Haskell (depth, pure FP): Scala 3 gives you most Haskell idioms but with JVM compromises. Haskell is the platonic version.
- → Rust (lateral, types-+-systems): For the part of “advanced types” Scala can’t help with — memory.
- → Clojure (depth, Lisp + JVM): The dynamic-Lisp pair to Scala’s static-Haskell-on-JVM.
- → Lean (depth, dependent types): For Scala devs who got hooked on type-level programming.
From Dart
- → Swift (lateral, native iOS): If your Flutter app needs native bridges.
- → Kotlin (lateral, native Android): Same.
- → TypeScript (lateral, web): Both targets the web; TS has more ecosystem.
- → Rust (depth, performance): For Flutter performance work or
flutter_rust_bridge.
From Elixir
- → Erlang (depth, ancestor): To understand BEAM at the metal level.
- → Gleam (lateral, types on BEAM): The typed sibling. Sound types + Elixir-flavored ergonomics.
- → Rust (depth, NIFs + types): Many Elixir hot paths get rewritten in Rust via Rustler.
- → Haskell (depth, pure FP): Different FP paradigm; complements actor model with pure functions.
From Haskell
- → Idris (depth, dependent + linear): The natural progression. QTT + dependent types.
- → Agda (depth, proofs): Even more focused on proof; less on programming.
- → Lean (depth, theorem proving + math): mathlib is the killer app.
- → Rust (lateral, applied FP): For the Haskeller who wants to ship production code with predictable performance.
- → OCaml (lateral, eager ML): Strict-by-default cousin; gets you out of laziness pitfalls.
From Clojure
- → Common Lisp (depth, Lisp ancestor): The mothership. CLOS + MOP + condition system + reader macros.
- → Scheme (lateral, minimal Lisp): Clojure stripped to its essence. Racket as the modern playground.
- → Elixir (lateral, dynamic functional): Different runtime; same FP-with-dynamic-types feel.
- → Haskell (depth, types): If you wanted typed FP after the Lisp epiphany.
From [[Languages/fsharp|F#]]
- → OCaml (depth, ML ancestor): F# is OCaml-on-.NET; meeting the original sharpens you.
- → Haskell (depth, pure + lazy): Pure FP with type classes; the Platonic FP.
- → Scala (lateral, JVM-equivalent): If you wanted to leave .NET.
- → Rust (lateral, systems): For native performance with strong types.
From Lua
- → JavaScript (lateral, similar simplicity): If you want a bigger ecosystem with similar dynamic feel.
- → Python (lateral, ecosystems): More batteries; similar accessibility.
- → Zig (depth, embedding host): If you embed Lua, Zig-as-host is a great pair.
- → Scheme (depth, language design): Lua’s semantics borrowed heavily from Scheme; learn the source.
From R
- → Python (lateral, broader data ecosystem): The other half of “what data scientists know in 2026”.
- → Julia (depth, performance + types): The natural progression for R devs hitting performance walls.
- → SQL (domain, data engineering): Most R workflows ultimately query a database; SQL fluency widens your impact.
- → TypeScript (domain, dashboards): For Shiny/Streamlit-equivalent rich apps using Observable Plot, D3, etc.
From Julia
- → Rust (depth, types + memory): For when Julia’s GC or precompile times limit you.
- → Python (lateral, ecosystem): For the deployment side of ML/data work.
- → Lean (depth, formal math): If you do scientific computing and care about correctness.
- → C + CUDA (domain, HPC): For low-level numeric kernels.
From Zig
- → Rust (lateral, more checks): Same niche; opposite ergonomics on the safety/simplicity tradeoff.
- → C (depth, the foundation): To understand what Zig is improving over.
- → Odin (lateral, peer): Same era of “modern systems lang”; allocator-as-context vs explicit allocator parameter.
From Nim
- → Rust (lateral, modern systems): More ecosystem; stricter; ownership instead of optional GC.
- → Python (lateral, scripting): Nim’s syntax was inspired by Python; cousins.
- → Zig (depth, simpler systems): For the part of Nim that “could just be data”.
From Crystal
- → Ruby (lateral, source paradigm): Crystal’s syntax is Ruby; the dynamic original deepens you.
- → Rust (depth, ownership): The other “compiled Ruby-ish” with stricter checks.
- → Elixir (lateral, BEAM): Different concurrency story; typed sibling pace.
From OCaml
- → Haskell (depth, lazy + classes): The lazy + type-class extension of ML.
- → Rust (lateral, ML descendant for systems): Rust’s option/result/match are pure ML.
- → [[Languages/fsharp|F#]] (lateral, OCaml-on-.NET): Direct cousin.
- → Coq (Rocq) (depth, dependent types): Same author lineage; CoQ is OCaml-flavored.
From Perl
- → Python (lateral, modern scripting): The community migration path.
- → Raku (not in 51, fka Perl 6) — for context.
- → Ruby (lateral, expressive dynamic): Influenced by Perl; better OO.
- → Clojure (depth, FP): For the Perl hacker who wants more abstraction.
From Erlang
- → Elixir (lateral, modern Erlang): What most Erlangers reach for 2015+.
- → Gleam (depth, types on BEAM): The typed sibling.
- → Pony (depth, refcaps): Compile-time data-race-freedom on top of actors.
From Racket
- → Scheme (lateral, ancestor): Racket descends from Scheme; visit the family.
- → Common Lisp (depth, the mothership): MOP, restarts, save-lisp-and-die.
- → Clojure (lateral, Lisp on JVM): For employability + Java interop.
- → Haskell (depth, types): For typed FP after the Lisp epiphany.
From Common Lisp
- → Clojure (lateral, modern Lisp): Newer ecosystem; JVM and JS hosts.
- → Racket (lateral, hygienic + lang): Different macro tradition.
- → Smalltalk (depth, the other live system): Image-based development cousin.
- → Haskell (depth, types): For the typed FP eye-opener.
From Scheme
- → Racket (lateral, modern descendant): The maximalist Scheme.
- → Common Lisp (depth, the maximal Lisp): Pragmatic vs minimalist tradition.
- → Clojure (lateral, JVM): For job-relevant Lisp.
From Fortran
- → Julia (lateral, modern numeric): The 2026 successor for new scientific code.
- → C + OpenMP (lateral, low-level HPC): For when you must integrate.
- → Rust (depth, types + safety): For long-lived scientific code.
- → Python + numpy/numba (domain, ecosystem): Where most new scientific computing happens.
From COBOL
- → Java (lateral, mainframe migration target): The conventional rewrite path.
- → [[Languages/csharp|C#]] (lateral, mainframe migration target): The other conventional rewrite path.
- → SQL (domain, data): COBOL is mostly data processing; SQL is the modern equivalent.
- → Python (lateral, scripting): For tooling around legacy systems.
From Ada
- → Rust (lateral, modern safety-critical): The natural successor for new safety-critical code.
- → SPARK (Ada subset, in
ada.md) (depth, formal verification): If your Ada is for high-assurance, SPARK is the next level. - → Haskell (depth, types): For the type-theory perspective.
From Pascal
- → [[Languages/csharp|C#]] (lateral, OO progression): What Anders Hejlsberg did after Delphi. Natural progression.
- → Rust (depth, types + ownership): For the safety-conscious Pascal alum.
- → Go (lateral, simple OO): Similar simplicity ethos.
From Prolog
- → Haskell (depth, declarative + types): Different declarative style; same “describe, don’t direct” mindset.
- → Lean (depth, theorem proving): The modern formal-reasoning successor.
- → Clojure (lateral, dynamic FP): For job-relevant declarative work.
From Tcl
- → Python (lateral, modern scripting): Most Tcl shops have ported.
- → Lua (lateral, embeddable): Tcl’s natural niche cousin.
- → Scheme (depth, design lessons): Different “everything is X” philosophy.
From Groovy
- → Kotlin (lateral, modern JVM scripting): What Gradle migrated to.
- → Scala (depth, typed + functional): Bigger jump but bigger reward.
- → Python (lateral, dynamic): Larger ecosystem; similar feel.
From Bash
- → Python (lateral, when bash gets gnarly): The conventional “I outgrew bash” path.
- → PowerShell (lateral, object-pipeline): Different mental model; stronger types.
- → Zig + clap (depth, replace bash with binaries): For tooling that needs to be portable + fast.
- → Rust (depth, replace bash): Same niche; long-lived tooling.
From PowerShell
- → Python (lateral, cross-platform scripting): Ubiquitous; complement.
- → [[Languages/csharp|C#]] (lateral, .NET deep dive): PowerShell IS .NET; learn the underlying.
- → TypeScript (lateral, ops scripting): For when your scripts run in CI/CD that’s JS-based.
From SQL
- → Python + pandas/duckdb/polars (lateral, programmatic data): The data-engineer’s Swiss army.
- → Rust (depth, building DB engines): If you’re the engineer behind the database.
- → Haskell (depth, query optimization theory): The type-theoretic perspective on relational algebra.
- → Datalog (not in 51) — for context — declarative recursion that SQL can almost do.
From V
- → Go (lateral, mature equivalent): What V was inspired by; much larger ecosystem.
- → Rust (depth, real ownership): For the safety claims V aspires to.
- → Zig (lateral, peer): Similar era; better-supported.
From Odin
- → Zig (lateral, peer): Same era; explicit allocators vs context allocators.
- → C (depth, foundation): Odin descends from C in spirit.
- → Rust (lateral, more checks): The “more types, less performance trust” cousin.
From Roc
- → Elm (not in 51) (lateral, ancestor): Roc descends from Elm.
- → Haskell (depth, FP foundations): Roc’s abilities are typeclass-equivalents.
- → Rust (lateral, build platforms): Roc platforms are typically Rust/Zig; learning host languages helps.
From Gleam
- → Elixir (lateral, BEAM peer): Same runtime; dynamic.
- → Erlang (depth, BEAM ancestor): Understand the platform deeply.
- → TypeScript (lateral, structural types): Gleam compiles to JS; pair well.
From Pony
- → Rust (lateral, types + ownership): Same “compile-time correctness” goal; different mechanism.
- → Erlang (depth, actor model origin): Pony’s actor model traces to Erlang.
- → Idris (depth, dependent types): For the type-theory continuation.
From Idris
- → Agda (lateral, peer): Different reflection emphasis; cubical Agda for HoTT.
- → Lean (lateral, peer + math): Lean has the bigger formalized math library.
- → Haskell (depth, applied FP): For job-relevant FP after dependent-types training.
- → Rust (depth, applied types): The realistic everyday use of strong types.
From Lean
- → Coq (Rocq) (lateral, peer): Different elaborator; massive verification corpus.
- → Agda (lateral, peer): More reflection; HoTT-native.
- → Idris (lateral, peer): More focus on programming with dependent types.
- → Haskell (depth, applied FP): For shipping code with strong types.
- → Rust (depth, applied types in industry): For paid type-theory work.
From Coq (Rocq)
- → Lean (lateral, peer): Younger, more programmer-friendly elaborator.
- → Agda (lateral, peer): More direct programming feel.
- → OCaml (depth, the host): Coq is implemented in OCaml; learning OCaml unlocks plugin development.
- → Idris (lateral, peer): For practical-programming-first dependent types.
From Agda
- → Lean (lateral, peer): Bigger math corpus.
- → Idris (lateral, peer): More “programmer-first” dependent types.
- → Coq (Rocq) (lateral, peer): The other major theorem prover.
- → Haskell (depth, applied FP): Agda is implemented in Haskell.
From Smalltalk
- → Common Lisp (depth, the other live system): The Lisp tradition’s image-based cousin.
- → Ruby (lateral, descendant): Ruby took method_missing + open classes from Smalltalk.
- → Clojure (lateral, modern dynamic): JVM-hosted; REPL-driven workflow descends from Smalltalk’s live model.
- → JavaScript (lateral, prototype OO): Self → JS lineage.
Common bridge clusters
Patterns that recur across many sources:
The functional pilgrimage
Any → Haskell → Idris/Agda/Lean/Coq (Rocq) First Haskell to learn pure FP and types. Then dependent types to see types-as-values.
The systems descent
Python/JavaScript → Go → Rust → Zig/C Each step trades dynamism for control.
The Lisp epiphany
Any → Scheme/Clojure → Racket → Common Lisp Scheme is the gateway, Racket is the maximalist, Common Lisp is the pragmatic mothership.
The actor enlightenment
Java/Python → Elixir → Erlang → Pony Elixir is the gateway; Pony is the type-system maximalist.
The dependent-types journey
Haskell → Idris → Agda → Lean/Coq (Rocq) Idris is the most “programmer-first”; Agda is the most reflective; Lean has the math corpus; Coq has the verification corpus.
The dynamic-to-typed evolution
JavaScript → TypeScript Python → Python+mypy (or Rust for the bigger leap) Ruby → Crystal (or Sorbet) Lua → Luau (Roblox) PHP → PHP+Psalm/PHPStan (or TypeScript for cross-context)
The “I want one language for everything” path
TypeScript (frontend) + Rust (backend + native) is the most common 2026 polyglot pair.
The math/formal-methods path
Python → Julia → Lean → Coq (Rocq)/Agda For scientists who graduate from “compute it” to “prove it”.
The “ship a startup” path
TypeScript (Next.js or React + RSC) + Elixir (Phoenix LiveView) is the under-rated 2026 pair if you can hire BEAM-curious people.
Anti-recommendations (don’t go here next)
Pairs that look related but tend to pessimize both:
- C++ as your “next” after Rust: Different mental models for ownership; you’ll fight C++ to write Rust idioms. Only do it if your job demands it.
- Haskell as your “next” after Lean: Lean’s elaborator subsumes most Haskell tricks; going backward is rarely revelatory.
- Ruby as your “next” after Python (or vice versa): Same niche, same tradeoffs. Pick one and go deep.
- JavaScript as your “next” after TypeScript: TS is JS + types; learning untyped JS is a regression.
- COBOL as a paradigm-shift: It isn’t. It’s a domain expansion (mainframes/legacy migration).
- Agda / Coq (Rocq) / Lean as your first FP language: Start with Haskell or OCaml. Dependent types compound on FP fluency.
- C++ as a paradigm-shift after C: It’s an extension, not a paradigm shift. For paradigm shift, learn Rust or Lisp.
- Scala as a “Java escape hatch” without committing to FP: You’ll write Java-with-funky-syntax and get the worst of both. Either go full Cats Effect / ZIO or stay with Kotlin.
How to choose your “next”
Three questions:
- What’s the goal? Job change → lateral + employability. Curiosity → depth. Domain expansion → domain.
- What do I most lack? Memory understanding → Rust. Type-theory → Haskell/Idris. Concurrency → Erlang/Pony. Live development → Smalltalk/CL.
- Will I actually finish a non-trivial project in it? Bridge value comes from finishing, not reading. Pick smaller if needed.
Cross-references
For per-language detail, see the 51 individual notes linked from _index. The recommendations here are grounded in their Idioms & style, Ecosystem, and God mode sections.
Citations
- This note is opinionated synthesis grounded in the 51 per-language notes (_index).
- Common community paths: Hacker News “from X to Y” threads, Reddit r/learnprogramming patterns, university curricula (CMU, MIT, Cambridge).
- Seven Languages in Seven Weeks (Bruce Tate) — the original “exposure” book.
- Programming Language Pragmatics (Michael Scott) — the comparative-paradigm textbook.
- The 51 per-language notes in _index are the underlying source.