HackerURLs

一次又一次被重新发现的经典。

同一个链接,相隔一年以上,一次又一次被人重新发现、再次冲上 Hacker News 首页。能经受住这种时间检验的,大多是值得一读再读的文章。每篇附中文标题,讨论最热的那些再加上中文导读和高赞评论翻译。

从名人堂开始
  • 4,700+篇经过时间检验的经典

Hall of fame

名人堂

在经典库里看全部精选

上首页次数最多、而且有中文导读的 30 篇。时间轴上每个黑点是一次上首页,空心点是一次没冲上去的投稿。

  1. 正在载入经典…

Archive

经典库

按第一次上首页的年份分布,点柱子筛选。

排序

    About

    这些经典是怎么挑出来的

    1. 01

      合并同一个链接

      读取 Hacker News 自 2006 年以来的全部链接投稿,把 http/https、www、跟踪参数等写法不同的同一篇文章合并成一条。

    2. 02

      只留经得起时间的

      同一链接至少两次拿到 50 分以上(约等于上首页),而且两次相隔一年以上;再由 AI 剔除状态页、产品首页和新闻事件。

    3. 03

      写导读、译评论

      上首页次数最多的 2,000 篇配上中文导读、"为什么经久不衰",并精选翻译 HN 高赞评论。导读由 AI 生成,可能有误。

    编程与软件工程journal.stuffwithstuff.com编辑精选

    你的函数是什么颜色?

    What Color Is Your Function?

    5次上首页
    9年跨度
    840累计得分
    425条评论

    2015 — 2024,它一次次回到首页

    黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。

    导读

    这篇经典文章用“函数有颜色”的比喻剖析了 async/await 式异步编程的核心缺陷:函数被分成同步(无色)和异步(红色)两类,红色函数会沿着调用链“传染”,迫使整个代码库改写。文章由此解释了为什么 Node 生态会全面倒向回调/异步风格,以及这种二分法给语言设计带来的长期代价。

    为什么经久不衰:它精准命名了异步编程中一个至今仍困扰各语言(JS、Python、Rust 等)的结构性问题,每次 async/await 之争兴起时都会被重新引用。

    关键词 异步编程async/await语言设计函数染色

    HN 评论精选

    函数染色问题本质上是效果系统问题,monad 是比 async/await 更通用的解法

    可以把“蓝色”大规模推广为“纯函数”,“红色”推广为“非纯函数”,最终结果本质上就是 Haskell。但仅有(纯/非纯)两色太受限了:蓝色函数行为一致且组合性极好,红色函数却种类繁多——异步、有状态、抛异常、非确定性、CPS、IO 副作用等等。我们真正需要的是一种表示不同种类的“红色”并让它们优雅组合的方式,而这正是 monad 和 monad transformer 所解决的问题。Java/C#/Go 都只引入了固定数量的“红色”和特定的连接方式,而 monad 是可泛化的方案。

    tel查看英文原文

    We can massively generalize this by calling "blue" "pure" and "red" "impure". The end result is essentially Haskell (but you can take it much further, too!). --- There's something horrifyingly restrictive about having merely (blue -> pure, red -> impure), though. All "blue" functions behave roughly the same (e.g., very, very nicely and compositionally) but "red" functions come in many classes: async, stateful, exception-throwing, non-deterministic, CPS'd, IO-effectful, combinations of the prior. What we want is a nice way of representing different kinds of red functions and how they all interact. What we'd also like is a nice way of composing different kinds of red functions so that the bundled piece has a sensible kind of redness too and we can keep composing. And this is exactly monads and monad transformers. There are other ways to achieve this end as well all under the general name "Effect Typing". Very cool stuff. But what I'd like to emphasize is that Java/C#/Go have not solved this larger problem. They each introduce a fixed number of "rednesses" and very specific ways that different kinds of red can be connected together. Monads are a generalizable solution. The situation is exactly the same as HOFs themselves. We've had subroutines and functions for a long time, but first-order and higher-order functions are a marked increase in power since you can now refer to these "function things" directly. Monads take the notion of "CPS Transform" and allow you to refer to it directly, to mark sections of code which use it and compose them intelligently. They allow you to invent your own kinds of redness on the fly and ensure that your custom colorations compose just as nicely as the built-in ones. If this article is even slightly interesting then you owe it to yourself to learn much more about effect typing. It'll change your world. (That and sum types, because nobody is served by a bunch of integers named Token.LEFT_BRACKET.)

    async 本质是倒退回协作式多任务,线程仍是相对最不坏的选择

    用过 Node 和 Tornado 之后,我对各种 async 方案都很反感。想想 90 年代初 Windows 和 Mac OS 的协作式多任务:必须显式让出控制权,否则整个系统卡死,后来被抢占式多任务取代,程序员可以放心调用阻塞 IO,由调度器处理。现在的 async 就像协作式多任务的回归,而且更糟:不仅要显式 yield,事件循环还不能好好利用多核,堆栈跟踪也不连贯,极难调试。理论上很快,但只要一个请求忘记 yield 就会堵死全局——用多进程加分发器解决的话,等于糟糕地重新发明了抢占式多任务。线程不完美,但除 STM 和 actor 模型外,它是痛苦最少的方案。

    overgard查看英文原文

    I'm really out on most of the "async" stuff, after having used it. (Mostly in Node and Tornado) Remember in the early 90s when Windows and Mac OS were "cooperatively" multitasked? Which is to say, you had to explicitly yield to allow other applications to run (or risk locking up the entire system). And then it was replaced with pre-emptive multitasking, which allowed the scheduler to figure out what process deserved CPU time, while allowing the programmer not to have to think about it. You could call a blocking IO function, and the OS would just go do something else while you waited. All this "async" stuff seems like a return of cooperative multitasking, only worse. Not only do I have to explicitly yield, but now it's to some event loop that can't even properly use multiple cores, or keep a coherent stack trace. It's a nightmare to debug. It's theoretically fast... except if one request forgets to yield, it can clog up the entire thing. I guess you use multiple processes for that and a dispatcher, but at that point you've basically reinvented preemptive multitasking... badly. Threads aren't perfect, but excluding STM and actor models they definitely suck the least.

    实践解法:把所有函数统一 promise 化,让“染色”不再成为问题

    我写 JavaScript 全栈好几年了,采用的做法是把一切都强制转成 promise——用作者的话说就是把一切都染成红色。同步代码混进异步代码也没关系,照样加进 promise 链即可立即 resolve;回调式库就包一层 promise。一切皆 promise 用起来非常好:任何东西随时可能变成异步而无需改变代码流程。额外的好处是错误处理位置可以自选——promise 被拒绝时会跳过链上后续操作直达 catch,你可以在一处统一处理错误,而不是每个操作后面都写一遍 if error。

    jenius查看英文原文

    So I've been writing javascript full time for a couple years at this point, client, server, and open source, and what I have adopted is coercing everything into promises, which I suppose would be the author's way of saying making everything red. If you have something that is not async mixed in with something that's async, you can still add it to the promise chain and it will resolve right away. If you have a library that uses callbacks or some other thing, you can just wrap it such that it now uses promises. And then of course you can always look for alternate libraries that use promises from the start and skip step as well. I've found that using promises for everything works super well. There is no confusion or doubt at all. Everything has the potential to branch into async at any time with no consequences and without complicating the flow. And an additional benefit is that rather than checking for errors after any operation you do, you choose where to check for errors. When a promise rejects, it skips everything else in the chain until it gets to a catch. So rather than running 4 async operations and doing an "if error do this" after each operation kind of deal, you can catch the error in once place and handle it once. Promises surpress the error in the promise chain until you choose to handle it, which is dangerous if you don't understand how promises work, but really useful once you do. There are really solid promise-based libraries for all common operations in node right now. When.js for general promises, composition, and coercion, rest.js for network requests, bookshelf and knex for database connection and orm stuff, etc. If you are a js developer, give them a shot! Don't get me wrong, I'm not trying to claim that this is better than any other language-level construct by any means, but if you are working in javascript, where you have to deal with javascript's limitations as a language, from experience I can say that working in an all-promises environment makes things quite pleasant.

    Zig 语言通过设计让 async/sync 函数无需区分颜色

    Zig 的函数是“色盲”的:https://kristoff.it/blog/zig-colorblind-async-await/

    jedisct1查看英文原文

    Zig’s functions are colorblind: https://kristoff.it/blog/zig-colorblind-async-await/

    历次讨论

    同类还值得读

    1. 开源应用架构

      The Architecture of Open Source Applications

      《开源软件架构》(AOSA)是一本在线免费书,邀请知名开源项目的作者亲自剖析其内部设计,涵盖 SQLAlchemy、LLVM、Audacity、Apache、Bash 等系统。

      编程与软件工程上首页 9 次 · 2011–2024aosabook.org编辑精选
    2. 编程语言简史:简短、不完整且多半错误

      A Brief, Incomplete, and Mostly Wrong History of Programming Languages

      一篇以戏谑、故意不准确的方式回顾编程语言史的博客文章,用夸张轶事和讽刺定义串起 Lisp、C、C++、Java、JavaScript、PHP 等语言。

      编程与软件工程上首页 8 次 · 2009–2021james-iry.blogspot.com
    3. SQLite 是如何测试的

      How SQLite is tested

      SQLite 官方文档页,系统介绍 SQLite 的测试体系:多种测试方法(TCL 测试、模糊测试、回归测试、静态分析等)和海量测试用例,展示了这个小型开源项目如何靠极致测试获得…

      编程与软件工程上首页 8 次 · 2009–2025sqlite.org编辑精选
    4. 高级编程语言(2009)

      Advanced programming languages (2009)

      Matt Might 的经典文章,按用途推荐“高级编程语言”:如果追求就业就选主流语言,如果追求表达力、学术研究或创业,则推荐 Haskell、OCaml、Scala 等函数式语…

      编程与软件工程上首页 8 次 · 2009–2022matt.might.net
    5. 我的 Forth 与栈机器经历

      Yosefk - My history with Forth & stack machines

      作者以亲身经历回顾了使用 Forth 语言和栈式机器的历程:既赞叹其简洁优雅、代码量小、可自举的优点,也坦率指出栈操作在实际编程中的痛苦,以及 Forth 社区文化中的问题。

      编程与软件工程上首页 8 次 · 2010–2024yosefk.com编辑精选

    打赏支持

    打赏二维码

    觉得有用,请作者喝杯咖啡。

    WeChat

    关注向阳乔木

    微信公众号「向阳乔木推荐看」

    微信公众号「向阳乔木推荐看」二维码

    微信扫一扫;在微信里打开本页时,长按二维码识别。