[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"consumer-news-detail-921":3,"consumer-news-interaction-921":41,"consumer-news-related-921":44},{"detail":4,"item":36},{"card":5,"schemaVersion":23,"fields":24,"content":30},{"id":6,"kind":7,"targetType":8,"targetId":9,"subtype":7,"typeLabel":10,"title":11,"subtitle":12,"summary":13,"coverUrl":14,"badgeText":15,"href":16,"sourceName":12,"meta":17,"metrics":20,"tags":21,"resolved":22},"NEWS_ARTICLE:921","news","NEWS_ARTICLE",921,"资讯","编程语言的「第三条道路」上，走得最远的其实是 C#","博客园","不必要求每个开发者都成为证明专家，而是把验证、内存安全、类型纪律，一层层织进语言和平台的基础设施里，让正确的代码成为默认路径","https:\u002F\u002Fimg2024.cnblogs.com\u002Fblog\u002F510\u002F202608\u002F510-20260830081613420-742582120.jpg","","\u002Fnews\u002F921",[18,19],"2026","软件开发",{},[19],true,"consumer-content-detail-v1",{"sourceName":12,"authorName":25,"categoryName":19,"summary":13,"description":13,"publishTime":26,"updateTime":27,"sourceUrl":28,"language":29},"张善友","2026-08-30T08:00","2026-09-02T20:37:56","https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360","中文",{"format":31,"policy":32,"normalized":22,"html":33,"text":34,"wordCount":35,"hasBody":22},"HTML","NEWS_CONTENT_V1","\u003Cblockquote>\n \u003Cp>\"测试只能证明 bug 的存在，却永远无法证明 bug 的缺席。\"\u003C\u002Fp>\n \u003Cp>—— Edsger Dijkstra\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch2>写在前面\u003C\u002Fh2>\n\u003Cp>最近读到一篇基于 OCaml 之父 Xavier Leroy 深度访谈的文章，标题叫《编程语言的\"第三条道路\"》\u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fn1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">[1]\u003C\u002Fa>。\u003C\u002Fp>\n\u003Cp>Leroy 是法国科学院院士、法兰西公学院教授，1996 年创造了 OCaml，2024 年拿下了 ACM SIGPLAN 编程语言软件奖。这场近 90 分钟的访谈横跨了函数式编程、形式化验证、内存管理和生成式 AI——几乎每个话题，都能直接映射到 C# 的处境上。\u003C\u002Fp>\n\u003Cp>读完后我有个越来越强烈的感受：\u003C\u002Fp>\n\u003Cp>\u003Cstrong>这篇文章讲的是\"第三条道路\"，而 C# 是这条路上商业化最成功、却最少被这样叙述的语言。OCaml 证明了这条路可行，C# 证明了这条路能赢。\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>下面分五条线索，聊聊这篇访谈和 C# 之间的隔空对话。\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"https:\u002F\u002Fi1.wp.com\u002Fimg2024.cnblogs.com\u002Fblog\u002F510\u002F202608\u002F510-20260830081613420-742582120.jpg?w=720&amp;quality=65&amp;strip=all\" alt=\"1\">\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>一、混血语言：C# 才是「又纯又脏」路线的商业冠军\u003C\u002Fh2>\n\u003Cp>Leroy 对 OCaml 的定位很有意思：\u003C\u002Fp>\n\u003Cblockquote>\n \u003Cp>\"OCaml 是一种优秀的函数式语言……但它同时也是一门相当不错的系统编程语言。\"\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>纯函数式语言（Haskell、Coq）活在学术象牙塔里，系统语言（C、C++）活在工程泥潭里。OCaml 不站队，两头都要，靠这种\"不媚俗\"的混血活了 30 年\u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fn1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">[1:1]\u003C\u002Fa>。\u003C\u002Fp>\n\u003Cp>但说实话，这条混血路线走得最远的其实是 C#——只是它做得更隐蔽：\u003C\u002Fp>\n\u003Cul>\n \u003Cli>\u003Cstrong>LINQ\u003C\u002Fstrong>：Erik Meijer 把 Haskell 的 monad 和查询综合\"偷运\"进了主流语言；\u003C\u002Fli>\n \u003Cli>\u003Cstrong>records、模式匹配、switch 表达式、init-only\u003C\u002Fstrong>：这些全是 ML 家族的家当，经由 F# 先在 .NET 里趟路，再反向输入给 C#；\u003C\u002Fli>\n \u003Cli>\u003Cstrong>async\u002Fawait\u003C\u002Fstrong>：原型是 F# 的 computation expressions——\"学术成果经工业界放大\"的教科书案例。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>这里有个常被忽略的事实：\u003Cstrong>F# 本身就是 OCaml 的直系兄弟\u003C\u002Fstrong>（Don Syme 在微软剑桥研究院起家时，做的就是\"OCaml for .NET\"）。\u003C\u002Fp>\n\u003Cp>所以 .NET 生态其实是混血双轨制——F# 保留了纯血 ML 的完整类型推断和不可变默认，C# 负责把这些特性\"平民化\"。\u003C\u002Fp>\n\u003Cp>比如 \u003Ccode>var\u003C\u002Fcode>：C# 只做局部类型推断，在 API 边界强制显式标注。这恰好踩中了 Leroy 说的权衡——全局推断固然优雅，但大规模项目需要显式签名充当文档\u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fn1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">[1:2]\u003C\u002Fa>。C# 没有追求完整的 Hindley-Milner 推断，不是不能，而是判断了对工程团队的阅读成本不划算。\u003C\u002Fp>\n\u003Cp>\u003Cstrong>这是 C# 一以贯之的设计哲学：不求理论上最纯，只求工程上最优。\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>二、GC 之争：C# 给出了第三种答案\u003C\u002Fh2>\n\u003Cp>访谈里 Leroy 抛出了一个反直觉的观点：\u003C\u002Fp>\n\u003Cblockquote>\n \u003Cp>\"手动内存管理并不总是更快。或者你需要是一位非常优秀的程序员才能让它总是更快。\"\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>他的论据很实在：GC 语言的对象分配是指针递增式的 bump-allocation，接近 O(1)；共享结构不需要拷贝，而手动管理下\"因为你不确定是不是唯一所有者，所以拷贝一份——但拷贝在时间和内存膨胀上都代价高昂\"\u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fn1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">[1:3]\u003C\u002Fa>。\u003C\u002Fp>\n\u003Cp>Jane Street 的案例最耐人寻味：高频交易领域每一微秒都是钱，他们却选了带 GC 的 OCaml 而不是 Rust——\u003Cstrong>因为人为错误的成本远高于 GC 开销\u003C\u002Fstrong>。\u003C\u002Fp>\n\u003Cp>面对\"GC vs 手动\"的站队题，C# 的回应比选边站更精明：\u003C\u002Fp>\n\u003Cp>\u003Cstrong>默认 GC，但系统性提供逃生舱。\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n \u003Cli>\u003Ccode>Span&lt;T&gt;\u003C\u002Fcode> \u002F \u003Ccode>Memory&lt;T&gt;\u003C\u002Fcode>：零分配地切片内存，不放弃 GC；\u003C\u002Fli>\n \u003Cli>值类型 + \u003Ccode>stackalloc\u003C\u002Fcode> + \u003Ccode>ArrayPool\u003C\u002Fcode>：覆盖高频热路径；\u003C\u002Fli>\n \u003Cli>NativeAOT：把 GC 的存在感压到极低，打进嵌入式和 CLI 启动场景。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>换句话说：OCaml 证明了\"GC 语言可以做系统编程\"，C#\u002F.NET 则进一步证明了\"GC 语言可以按需在单个函数尺度上做手动内存决策\"。\u003C\u002Fp>\n\u003Cp>这比 Rust 的全局所有权纪律更符合 Leroy 那套\"组织经济学\"逻辑——团队里不是每个人都需要精通生命周期，但热路径上的那个人手里有工具。\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>三、并发哲学：Leroy 大概会更喜欢 Orleans\u003C\u002Fh2>\n\u003Cp>访谈里最生动的一段，是 Leroy 吐槽共享内存并发：\u003C\u002Fp>\n\u003Cblockquote>\n \u003Cp>\"共享内存并发就像你想和邻居交流，你破门而入，移动他们家的家具，等他们回来时会说'哦，有东西被移动了，大概是想告诉我什么'……也许你可以直接去\u003Cstrong>见\u003C\u002Fstrong>你的邻居？——这就是消息传递。\"\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>他推崇的是 Erlang 风格的 Actor 模型\u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fn1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">[1:4]\u003C\u002Fa>。\u003C\u002Fp>\n\u003Cp>有意思的是，C# 主线走的是 async\u002Fawait + 共享状态的老路，但 \u003Cstrong>Orleans 的 Virtual Actor Model\u003C\u002Fstrong> 就是 .NET 世界对消息传递的完整回答：grain 之间不可共享状态、只能收发消息，单机到集群共用同一套心智模型。\u003C\u002Fp>\n\u003Cp>再加上：\u003C\u002Fp>\n\u003Cul>\n \u003Cli>\u003Ccode>System.Threading.Channels\u003C\u002Fcode>：标准的 CSP 管道；\u003C\u002Fli>\n \u003Cli>TPL Dataflow：数据流网络；\u003C\u002Fli>\n \u003Cli>async\u002Fawait：任务并发。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>C# 其实是把三种并发范式都摆上了货架。\u003C\u002Fp>\n\u003Cp>这里有个颇具讽刺意味的对照：OCaml 5 为了 Jane Street 的需求在共享内存上做了妥协，而 C# 这个\"共享内存出身\"的语言，反而把 Actor 模型做成了工业级产品。\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>四、形式化验证：C# 是「轻验证」路线的极致\u003C\u002Fh2>\n\u003Cp>文章里有一张三种形式化方法的对比表\u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fn1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">[1:5]\u003C\u002Fa>：\u003C\u002Fp>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>方法\u003C\u002Fth>\n   \u003Cth>自动化程度\u003C\u002Fth>\n   \u003Cth>成本比（vs 写代码）\u003C\u002Fth>\n   \u003Cth>典型工具\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>类型系统\u003C\u002Ftd>\n   \u003Ctd>全自动\u003C\u002Ftd>\n   \u003Ctd>0.1x\u003C\u002Ftd>\n   \u003Ctd>OCaml \u002F TypeScript\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>静态分析\u003C\u002Ftd>\n   \u003Ctd>全自动\u003C\u002Ftd>\n   \u003Ctd>0.5x\u003C\u002Ftd>\n   \u003Ctd>Infer, Astrée\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>程序证明\u003C\u002Ftd>\n   \u003Ctd>交互式\u003C\u002Ftd>\n   \u003Ctd>10–50x\u003C\u002Ftd>\n   \u003Ctd>CompCert, seL4, Lean\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>C# 在\"10–50x\"那层基本缺席（Spec# 和 Code Contracts 都死在了沙滩上），但在 0.1x–0.5x 区间做到了极致：\u003C\u002Fp>\n\u003Cp>\u003Cstrong>可空引用类型（C# 8+）\u003C\u002Fstrong>\u003Cbr>\n  本质上是把\"十亿美元错误\"变成编译期流分析问题。不用写一行证明，编译器替你盯着每一个可能为 null 的路径——这是向验证迈出的最实用一步。\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Roslyn 编译器平台\u003C\u002Fstrong>\u003Cbr>\n  Analyzer 和 Source Generator 让每个团队都能低成本编写自己的静态验证规则。等于把\"静态分析\"这一层民主化了。\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Dafny\u003C\u002Fstrong>\u003Cbr>\n  微软研究院真正做程序证明的语言，可以把 C# 作为编译目标之一。重验证的路线，微软也没完全放弃。\u003C\u002Fp>\n\u003Cp>Leroy 花了大半辈子在 CompCert 上——一个携带数学证明、保证\"编译器不会引入源程序中不存在的 bug\"的 C 编译器，2026 年 3 月还帮空客 ATR 42\u002F72 的航电系统拿下了 DO-178C 认证\u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fn1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">[1:6]\u003C\u002Fa>。\u003C\u002Fp>\n\u003Cp>C# 走不了这条路，也不需要走。\u003Cstrong>它的策略是：把验证的成本压到接近于零，让 99% 的普通项目也用得起。\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>五、AI 时代：C# 最大的隐藏优势\u003C\u002Fh2>\n\u003Cp>访谈最尖锐的部分是关于 LLM 的。Leroy 作为 OCaml 维护者，吐槽非常直接：\u003C\u002Fp>\n\u003Cblockquote>\n \u003Cp>\"我们收到了很多明显由 AI 生成的 issue。10 份报告里可能只有 1 份是好的。每份报告都有好几页——详细的解释、复现步骤——但最终什么也复现不了。\"\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cblockquote>\n \u003Cp>\"对我来说，每一行新代码都是负债。我不想要海量代码，我要的是 50 行经过多年打磨的代码。\"\u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fn1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">[1:7]\u003C\u002Fa>\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>他的核心警告是：\u003Cstrong>AI 降低了\"写代码\"的成本，但没有（甚至提高了）\"验证正确性\"的成本。\u003C\u002Fstrong> 程序员从\"写代码者\"变成\"代码审查者\"，工作并没有变轻松，只是从一种认知负荷切换到另一种\u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fn1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">[1:8]\u003C\u002Fa>。\u003C\u002Fp>\n\u003Cp>在这个语境下，C# 的位置其实相当好：\u003C\u002Fp>\n\u003Cp>\u003Cstrong>第一，强静态类型 + nullable 流分析 + 全套 Analyzer，构成了一道机器可自动检查的质量门槛。\u003C\u002Fstrong> AI 生成的 slop，在编译器这一关就会被过滤掉一大半。\u003C\u002Fp>\n\u003Cp>\u003Cstrong>第二，Roslyn 是 compiler-as-a-service。\u003C\u002Fstrong> Agent 可以程序化地调用编译、拿到结构化诊断、再迭代修正——C# 大概是主流语言里最适合做\"LLM 生成 → 编译器反馈 → 自动修正\"闭环的之一。\u003C\u002Fp>\n\u003Cp>\u003Cstrong>第三，Leroy 的愿景是\"AI 生成代码的同时生成一份 Lean\u002FCoq 证明\"。\u003C\u002Fstrong> 离 C# 最近的现实版是：AI 生成代码，同时生成 analyzer 规则和属性测试（Property-Based Testing）。证明不必是数学形式的，可执行的规约也是证明。\u003C\u002Fp>\n\u003Cp>顺便说一句 DDD：C# 的 records、不可变值对象、模式匹配做领域建模已经很顺手，但真正完整的\"用类型让非法状态不可表示\"还得看 F# 的路数（Scott Wlaschin 的 \u003Cem>Domain Modeling Made Functional\u003C\u002Fem> 就是这套思路）。做领域对象投影、工作流 DAG 这类强结构化场景，F# 的判别联合 + 编译期完备性检查，比 C# 的 class 层级更贴合\"建模即验证\"。\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>结语：Leroy 的执念，C# 的回答\u003C\u002Fh2>\n\u003Cp>访谈结尾，Leroy 说了一段让我印象很深的话：\u003C\u002Fp>\n\u003Cblockquote>\n \u003Cp>\"写出代码从来不是终点。理解代码为什么正确，才是真正的编程能力。\"\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>一个学术语言的守护者，用三十年证明\"可靠性与工程实用可以共存\"。\u003C\u002Fp>\n\u003Cp>而 C# 用另一种方式回应了同样的命题：\u003Cstrong>不必要求每个开发者都成为证明专家，而是把验证、内存安全、类型纪律，一层层织进语言和平台的基础设施里，让正确的代码成为默认路径。\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>OCaml 是第三条道路的宣言，C# 是第三条道路的基建。\u003C\u002Fp>\n\u003Cp>Dijkstra 那句话放在今天依然紧迫：我们应该用自己完全理解的程序，去解决未知世界的问题——而不是反之。\u003C\u002Fp>\n\u003Cp>只不过在 2026 年，帮你\"理解程序\"的，除了你的大脑，还多了一个编译器，和一个永远在生成\"差不多正确\"代码的 AI。\u003C\u002Fp>\n\u003Cp>选一门能让编译器替你吵架的语言，可能是这个时代最务实的浪漫。\u003C\u002Fp>\n\u003Chr>\n\u003Cp>\u003Cem>本文基于 Xavier Leroy 在 The Peterman Podcast（2026 年 7 月）访谈的解读文章展开，部分观点为作者延伸。\u003C\u002Fem>\u003C\u002Fp>\n\u003Chr>\n\n \u003Col>\n  \u003Cli>\u003Cp>\u003Ca href=\"https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F2063254883969544605\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F2063254883969544605\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fnref1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">↩︎\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fnref1:1\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">↩︎\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fnref1:2\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">↩︎\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fnref1:3\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">↩︎\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fnref1:4\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">↩︎\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fnref1:5\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">↩︎\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fnref1:6\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">↩︎\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fnref1:7\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">↩︎\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fwww.cnblogs.com\u002Fshanyou\u002Fp\u002F22759360#fnref1:8\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">↩︎\u003C\u002Fa>\u003C\u002Fp>\u003C\u002Fli>\n \u003C\u002Fol>","\"测试只能证明 bug 的存在，却永远无法证明 bug 的缺席。\" —— Edsger Dijkstra 写在前面 最近读到一篇基于 OCaml 之父 Xavier Leroy 深度访谈的文章，标题叫《编程语言的\"第三条道路\"》[1]。 Leroy 是法国科学院院士、法兰西公学院教授，1996 年创造了 OCaml，2024 年拿下了 ACM SIGPLAN 编程语言软件奖。这场近 90 分钟的访谈横跨了函数式编程、形式化验证、内存管理和生成式 AI——几乎每个话题，都能直接映射到 C# 的处境上。 读完后我有个越来越强烈的感受： 这篇文章讲的是\"第三条道路\"，而 C# 是这条路上商业化最成功、却最少被这样叙述的语言。OCaml 证明了这条路可行，C# 证明了这条路能赢。 下面分五条线索，聊聊这篇访谈和 C# 之间的隔空对话。 一、混血语言：C# 才是「又纯又脏」路线的商业冠军 Leroy 对 OCaml 的定位很有意思： \"OCaml 是一种优秀的函数式语言……但它同时也是一门相当不错的系统编程语言。\" 纯函数式语言（Haskell、Coq）活在学术象牙塔里，系统语言（C、C++）活在工程泥潭里。OCaml 不站队，两头都要，靠这种\"不媚俗\"的混血活了 30 年[1:1]。 但说实话，这条混血路线走得最远的其实是 C#——只是它做得更隐蔽： LINQ：Erik Meijer 把 Haskell 的 monad 和查询综合\"偷运\"进了主流语言； records、模式匹配、switch 表达式、init-only：这些全是 ML 家族的家当，经由 F# 先在 .NET 里趟路，再反向输入给 C#； async\u002Fawait：原型是 F# 的 computation expressions——\"学术成果经工业界放大\"的教科书案例。 这里有个常被忽略的事实：F# 本身就是 OCaml 的直系兄弟（Don Syme 在微软剑桥研究院起家时，做的就是\"OCaml for .NET\"）。 所以 .NET 生态其实是混血双轨制——F# 保留了纯血 ML 的完整类型推断和不可变默认，C# 负责把这些特性\"平民化\"。 比如 var：C# 只做局部类型推断，在 API 边界强制显式标注。这恰好踩中了 Leroy 说的权衡——全局推断固然优雅，但大规模项目需要显式签名充当文档[1:2]。C# 没有追求完整的 Hindley-Milner 推断，不是不能，而是判断了对工程团队的阅读成本不划算。 这是 C# 一以贯之的设计哲学：不求理论上最纯，只求工程上最优。 二、GC 之争：C# 给出了第三种答案 访谈里 Leroy 抛出了一个反直觉的观点： \"手动内存管理并不总是更快。或者你需要是一位非常优秀的程序员才能让它总是更快。\" 他的论据很实在：GC 语言的对象分配是指针递增式的 bump-allocation，接近 O(1)；共享结构不需要拷贝，而手动管理下\"因为你不确定是不是唯一所有者，所以拷贝一份——但拷贝在时间和内存膨胀上都代价高昂\"[1:3]。 Jane Street 的案例最耐人寻味：高频交易领域每一微秒都是钱，他们却选了带 GC 的 OCaml 而不是 Rust——因为人为错误的成本远高于 GC 开销。 面对\"GC vs 手动\"的站队题，C# 的回应比选边站更精明： 默认 GC，但系统性提供逃生舱。 Span\u003CT> \u002F Memory\u003CT>：零分配地切片内存，不放弃 GC； 值类型 + stackalloc + ArrayPool：覆盖高频热路径； NativeAOT：把 GC 的存在感压到极低，打进嵌入式和 CLI 启动场景。 换句话说：OCaml 证明了\"GC 语言可以做系统编程\"，C#\u002F.NET 则进一步证明了\"GC 语言可以按需在单个函数尺度上做手动内存决策\"。 这比 Rust 的全局所有权纪律更符合 Leroy 那套\"组织经济学\"逻辑——团队里不是每个人都需要精通生命周期，但热路径上的那个人手里有工具。 三、并发哲学：Leroy 大概会更喜欢 Orleans 访谈里最生动的一段，是 Leroy 吐槽共享内存并发： \"共享内存并发就像你想和邻居交流，你破门而入，移动他们家的家具，等他们回来时会说'哦，有东西被移动了，大概是想告诉我什么'……也许你可以直接去见你的邻居？——这就是消息传递。\" 他推崇的是 Erlang 风格的 Actor 模型[1:4]。 有意思的是，C# 主线走的是 async\u002Fawait + 共享状态的老路，但 Orleans 的 Virtual Actor Model 就是 .NET 世界对消息传递的完整回答：grain 之间不可共享状态、只能收发消息，单机到集群共用同一套心智模型。 再加上： System.Threading.Channels：标准的 CSP 管道； TPL Dataflow：数据流网络； async\u002Fawait：任务并发。 C# 其实是把三种并发范式都摆上了货架。 这里有个颇具讽刺意味的对照：OCaml 5 为了 Jane Street 的需求在共享内存上做了妥协，而 C# 这个\"共享内存出身\"的语言，反而把 Actor 模型做成了工业级产品。 四、形式化验证：C# 是「轻验证」路线的极致 文章里有一张三种形式化方法的对比表[1:5]： 方法 自动化程度 成本比（vs 写代码） 典型工具 类型系统 全自动 0.1x OCaml \u002F TypeScript 静态分析 全自动 0.5x Infer, Astrée 程序证明 交互式 10–50x CompCert, seL4, Lean C# 在\"10–50x\"那层基本缺席（Spec# 和 Code Contracts 都死在了沙滩上），但在 0.1x–0.5x 区间做到了极致： 可空引用类型（C# 8+） 本质上是把\"十亿美元错误\"变成编译期流分析问题。不用写一行证明，编译器替你盯着每一个可能为 null 的路径——这是向验证迈出的最实用一步。 Roslyn 编译器平台 Analyzer 和 Source Generator 让每个团队都能低成本编写自己的静态验证规则。等于把\"静态分析\"这一层民主化了。 Dafny 微软研究院真正做程序证明的语言，可以把 C# 作为编译目标之一。重验证的路线，微软也没完全放弃。 Leroy 花了大半辈子在 CompCert 上——一个携带数学证明、保证\"编译器不会引入源程序中不存在的 bug\"的 C 编译器，2026 年 3 月还帮空客 ATR 42\u002F72 的航电系统拿下了 DO-178C 认证[1:6]。 C# 走不了这条路，也不需要走。它的策略是：把验证的成本压到接近于零，让 99% 的普通项目也用得起。 五、AI 时代：C# 最大的隐藏优势 访谈最尖锐的部分是关于 LLM 的。Leroy 作为 OCaml 维护者，吐槽非常直接： \"我们收到了很多明显由 AI 生成的 issue。10 份报告里可能只有 1 份是好的。每份报告都有好几页——详细的解释、复现步骤——但最终什么也复现不了。\" \"对我来说，每一行新代码都是负债。我不想要海量代码，我要的是 50 行经过多年打磨的代码。\"[1:7] 他的核心警告是：AI 降低了\"写代码\"的成本，但没有（甚至提高了）\"验证正确性\"的成本。 程序员从\"写代码者\"变成\"代码审查者\"，工作并没有变轻松，只是从一种认知负荷切换到另一种[1:8]。 在这个语境下，C# 的位置其实相当好： 第一，强静态类型 + nullable 流分析 + 全套 Analyzer，构成了一道机器可自动检查的质量门槛。 AI 生成的 slop，在编译器这一关就会被过滤掉一大半。 第二，Roslyn 是 compiler-as-a-service。 Agent 可以程序化地调用编译、拿到结构化诊断、再迭代修正——C# 大概是主流语言里最适合做\"LLM 生成 → 编译器反馈 → 自动修正\"闭环的之一。 第三，Leroy 的愿景是\"AI 生成代码的同时生成一份 Lean\u002FCoq 证明\"。 离 C# 最近的现实版是：AI 生成代码，同时生成 analyzer 规则和属性测试（Property-Based Testing）。证明不必是数学形式的，可执行的规约也是证明。 顺便说一句 DDD：C# 的 records、不可变值对象、模式匹配做领域建模已经很顺手，但真正完整的\"用类型让非法状态不可表示\"还得看 F# 的路数（Scott Wlaschin 的 Domain Modeling Made Functional 就是这套思路）。做领域对象投影、工作流 DAG 这类强结构化场景，F# 的判别联合 + 编译期完备性检查，比 C# 的 class 层级更贴合\"建模即验证\"。 结语：Leroy 的执念，C# 的回答 访谈结尾，Leroy 说了一段让我印象很深的话： \"写出代码从来不是终点。理解代码为什么正确，才是真正的编程能力。\" 一个学术语言的守护者，用三十年证明\"可靠性与工程实用可以共存\"。 而 C# 用另一种方式回应了同样的命题：不必要求每个开发者都成为证明专家，而是把验证、内存安全、类型纪律，一层层织进语言和平台的基础设施里，让正确的代码成为默认路径。 OCaml 是第三条道路的宣言，C# 是第三条道路的基建。 Dijkstra 那句话放在今天依然紧迫：我们应该用自己完全理解的程序，去解决未知世界的问题——而不是反之。 只不过在 2026 年，帮你\"理解程序\"的，除了你的大脑，还多了一个编译器，和一个永远在生成\"差不多正确\"代码的 AI。 选一门能让编译器替你吵架的语言，可能是这个时代最务实的浪漫。 本文基于 Xavier Leroy 在 The Peterman Podcast（2026 年 7 月）访谈的解读文章展开，部分观点为作者延伸。 https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F2063254883969544605 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎",3799,{"id":6,"kind":7,"title":11,"summary":13,"image":14,"href":16,"meta":37,"badge":10,"author":12,"stats":-1,"accent":38,"coverRatio":39,"tags":40},"2026 · 软件开发","#2563eb","16 \u002F 10",[19],{"targetType":8,"targetId":9,"likedByMe":42,"likeCount":43,"commentCount":43,"contentLikeCount":43,"contentCommentCount":43,"sourceLikeCount":43,"sourceCommentCount":43},false,0,[45,51,58,64,70,77,84,91],{"id":46,"kind":7,"title":47,"summary":48,"image":15,"href":49,"meta":37,"badge":10,"author":12,"stats":-1,"accent":38,"coverRatio":39,"tags":50},"NEWS_ARTICLE:832","用 runtime-async 写一个支持 async\u002Fawait 的轻量脚本引擎","起因：一个好奇 事情的开头很简单。 给 .NET 做过动态脚本的人大概都碰到过同一堵墙：表达式树也好、Reflection.Emit 也好，都很难支持 async\u002Fawait。原因不在语法，而在 await 的实现方式——C# 编译器要为每个 async 方法生成一个状态机结构体，把方法体切成若干片","\u002Fnews\u002F832",[19],{"id":52,"kind":7,"title":53,"summary":54,"image":55,"href":56,"meta":37,"badge":10,"author":12,"stats":-1,"accent":38,"coverRatio":39,"tags":57},"NEWS_ARTICLE:855","被罚了500后，整个人都变老实了","我们组有个同事，以前是那种闲不住的人。现在也闲不住 只不过是不敢动了。 去年部门空降了一位新总监，阿里P8，第一次全员会PPT上就八个大字：拥抱变化，永不言弃。 新领导上来搞流程改革，每个模块指定Owner，出事追责到人，A级事故罚款500起步，B级300 依次类推，发版上线改配置全走审批。说实话之","https:\u002F\u002Fimg2024.cnblogs.com\u002Fblog\u002F273387\u002F202608\u002F273387-20260818222617092-925481998.png","\u002Fnews\u002F855",[19],{"id":59,"kind":7,"title":60,"summary":61,"image":15,"href":62,"meta":37,"badge":10,"author":12,"stats":-1,"accent":38,"coverRatio":39,"tags":63},"NEWS_ARTICLE:862","go中make声明切片, 修改切片,append给切片扩容,合并切片,复制切片","make 声明切片 make([]类型, 长度， 容量) kage main import (&quot;fmt&quot;) \u002F\u002F 入口函数 func main() { \u002F\u002F make 声明切片，长度是4， 容量是10 var sliceArr1 = make([]int, 4, 10) fmt.","\u002Fnews\u002F862",[19],{"id":65,"kind":7,"title":66,"summary":67,"image":15,"href":68,"meta":37,"badge":10,"author":12,"stats":-1,"accent":38,"coverRatio":39,"tags":69},"NEWS_ARTICLE:866","Spring Boot事件监听，这东西到底解决啥问题？","一、先聊个场景，你就明白这玩意儿干啥的了 点过外卖吧？那咱们就用这个场景来说事。 你掏出手机下了单，付了钱。接下来会发生啥？ 厨房那头开始备菜炒菜（这件事耽误不得，客户饿着呢） 手机收到一条短信：&quot;您的订单已收到，预计30分钟送达&quot; 你的会员账户里多了一堆积分 店长那个收银小喇叭","\u002Fnews\u002F866",[19],{"id":71,"kind":7,"title":72,"summary":73,"image":74,"href":75,"meta":37,"badge":10,"author":12,"stats":-1,"accent":38,"coverRatio":39,"tags":76},"NEWS_ARTICLE:881","RSA 密码传输加密通用接入方案","@目录前言一、介绍二、RSA 在本方案中的角色三、密文协议格式四、密钥生成与 Apollo 配置4.1 编译工具类4.2 执行生成密钥4.3 执行输出示例4.4 Apollo 配置示例五、后端接入方式AOP 注解示例六、后端解密流程七、前端接入方式7.1 获取公钥和 nonce7.2 使用 RSA-","https:\u002F\u002Fimg2024.cnblogs.com\u002Fblog\u002F1867541\u002F202608\u002F1867541-20260831165110853-162420906.png","\u002Fnews\u002F881",[19],{"id":78,"kind":7,"title":79,"summary":80,"image":81,"href":82,"meta":37,"badge":10,"author":12,"stats":-1,"accent":38,"coverRatio":39,"tags":83},"NEWS_ARTICLE:888","[开源] LogCrate：免解压、支持筛选和 AI 分析的 PC 端桌面日志工具","日常排查客户软件运行问题时，经常需要反复下载日志、解压缩，再从一堆文件里慢慢翻找，过程比较麻烦；而且很多日志工具也不支持针对具体字段进行筛选。 对比了一些市面上的日志分析工具后，发现能够同时兼容归档阅读、目录监控、到达通知、结构化筛选和 AI 分析的工具并不多，于是就自己动手做了一款。 PS：自己做","https:\u002F\u002Fiili.io\u002FCy4ztaa.png","\u002Fnews\u002F888",[19],{"id":85,"kind":7,"title":86,"summary":87,"image":88,"href":89,"meta":37,"badge":10,"author":12,"stats":-1,"accent":38,"coverRatio":39,"tags":90},"NEWS_ARTICLE:900","java 多线程开发系列之七：玩转多线程（线程的协作）","线程的协作多种多样，这次主要说说wait和notify两种Object的方法。这也是java早期原生的重要的协作机制之一。先说下这两个英文单词：wait [weɪt] v.等待;等候;(尤指长期地)希望，盼望，期待notify [ˈnəʊtɪfaɪ] vt.通知;(正式)通报;也就是一个等待，一个通","https:\u002F\u002Fimg2024.cnblogs.com\u002Fblog\u002F704073\u002F202608\u002F704073-20260831103138251-1707185366.png","\u002Fnews\u002F900",[19],{"id":92,"kind":7,"title":93,"summary":94,"image":15,"href":95,"meta":37,"badge":10,"author":12,"stats":-1,"accent":38,"coverRatio":39,"tags":96},"NEWS_ARTICLE:902","DeepSeek Harness 插件","准备环境 dsh 从源码运行，见 dsh 说明。或见之前分享的 DeepSeek Harness 开始。 开发插件 依照 dsh 文档，动手做一遍： 第一个插件: https:\u002F\u002Fdeepseek-harness.github.io\u002Fdeepseek-harness\u002Fdevelop\u002Fbasic\u002F 第","\u002Fnews\u002F902",[19]]