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编辑精选

    我写过的最难的程序——代码格式化器如何工作(2015)

    The Hardest Program I've Ever Written – How a code formatter works (2015)

    5次上首页
    10年跨度
    1,408累计得分
    471条评论

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

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

    导读

    这是 Bob Nystrom 回顾自己编写 Dart 代码格式化器(dartfmt)的文章。他指出,格式化器表面上只是“读入字符串、写出字符串”,却因为要全局决定断行与缩进而变得极其困难:一处换行会改变后续缩进,进而影响其他换行,无法简单套用动态规划。文章详细拆解了这些权衡与实现难点。

    为什么经久不衰:它揭示了“自动格式化”这一日常工具背后被低估的复杂度,是理解 dartfmt、Prettier 等格式化器设计取舍的经典入口,十年后仍被反复讨论。

    关键词 代码格式化Dartpretty printerPrettier

    HN 评论精选

    推荐 Wadler 的代数 pretty printer 算法,优雅且实用。

    Philip Wadler 有一篇开创性论文,用代数建模来实现 pretty printer。如今大多数语言都有该算法的实现,还有一些提升性能的新进展。这个算法非常优雅,用起来很愉快。Elixir 的格式化器用了它的变体,标准库里也有。我个人用它写过一个 GraphQL 查询格式化器,代码量很少但效果很强。如果你要做类似的事,一定要看看。

    QuinnWilton查看英文原文

    Philip Wadler has a seminal paper [0] on implementing pretty printers by modeling them using an algebra. There's implementations of the algorithm in most programming languages nowadays, and some state of the art advances that help with performance [1] It's a very elegant algorithm, and is very pleasant to work. Elixir's formatter uses a variant of it [2], and it appears in the standard library [3]. I've personally made use of it to write a code formatter for GraphQL queries, and it was a very small amount of code for some powerful results. Definitely take a look if you ever need to do something like this. [0] https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf [1] https://jyp.github.io/pdf/Prettiest.pdf [2] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.2200 [3] https://hexdocs.pm/elixir/Inspect.Algebra.html

    质疑 dartfmt 为何不能用动态规划,推测差异在于代码需要匹配兄弟节点缩进。

    “最佳”是整个被格式化语句的属性:一个换行会改变语句其余部分的缩进,进而影响其他换行——抱歉,Knuth,这次没有动态规划。但 TeX 的断行算法也是如此:最佳是整个段落的属性,换行会改变段落其余缩进……可 TeX 用了动态规划。所以值得看看这个问题到底有何不同(为什么动态规划对 TeX 有效、对 dartfmt 无效)。也许 Knuth 选的“最佳”定义恰好适合动态规划;也许 TeX 算法也可能很贵,只是段落与代码语句的可行断点分布不同。补充:一个相关区别可能是,格式化代码时必须把缩进与同嵌套层的前一个兄弟节点匹配。

    svat查看英文原文

    > Note that “best” is a property of the entire statement being formatted. A line break changes the indentation of the remainder of the statement, which in turn affects which other line breaks are needed. Sorry, Knuth. No dynamic programming this time. For what it's worth, the same is true of TeX's line-breaking algorithm too: “best” is a property of the entire paragraph being formatted; a line break can change the indentation of the remainder of the paragraph (in many ways, but most obviously: discretionary hyphens with nontrivial pre- and post- texts), which in turn affects which other line breaks are needed. And yet TeX uses dynamic programming. So it would be interesting to see how this specific problem differs. (Why dynamic programming works for TeX but not for dartfmt.) Perhaps Knuth chose a definition of "best" that is amenable to dynamic programming (after all he had quite a bit of freedom; it doesn't take much to beat the naive first-fit/best-fit line-breaking algorithms as used in Word etc), or perhaps TeX's algorithm too can be expensive but in practice paragraphs just tend to have a different distribution of feasible breakpoints than code statements. Knuth and Plass's (very readable!) paper on Breaking Paragraphs into Lines is here: http://www.eprg.org/G53DOC/pdfs/knuth-plass-breaking.pdf Edit: Ah, I think one relevant difference is probably that when formatting code, one has to "match up" indentation with the previous corresponding sibling of the same nesting level, while with paragraphs the amount of required state is smaller: given a particular line break and indentation, the remainder of a paragraph can always be formatted in the same way, while a code formatter also has to "remember" all previous parent expressions' indentation. (This reason is different from what is directly implied by the quoted statement though…)

    Prettier 选择简单规则加大量特例,而非穷举加权,认为不存在通用解法。

    我在做 Prettier 之前读过这篇,说实话有点吓人 :) 我不确信穷举加权方法是个好主意:计算量极大,而且很难预测打印器会做什么。Prettier 反而基于一个简单想法:如果放不下一行,就断开最外层的父级。这条简单规则(用 Wadler IR 实现)高效且输出通常好看。难的是花约六个月全职,为人类习惯的特殊写法逐个加特例。这里面没有计算机科学层面的难题,只是大量特例;我不相信有通用解法,只能硬啃。最后最烦的是注释,它们无处不在,正确打印超级麻烦。总的来说并不真的难,只是工作量巨大。

    vjeux查看英文原文

    I read this before working on prettier and it was a bit scary to be honest :) I wasn’t convinced that the exhaustive approach with weigths was a good idea. It makes it computationally super intensive and hard to predict what the printer would do. Instead prettier runs on a simple idea: if something doesn’t fit in one line, break the outermost parent. This simple rule (implemented via the Wadler IR) is efficient to implement and makes the output generally look good. Then the hard part was to go through the very looong (took me ~6 months full time) process of adding special cases for every constructs that human write in a special way. There is nothing in there that’s hard at a computer science level, it’s just a lot of special cases. I don’t believe that there’s a general solution for it, you just need to slog through it. And the last annoying thing are comments, they can be everywhere and are super annoying to print correctly. Overall, it wasn’t really hard, but a lot of work.

    自动格式化器无法理解开发者意图,许多大项目因此拒绝使用。

    据我所知,没有格式化器能理解意图。比如我希望接收 9 个参数的 canvas.drawImage 调用把参数 2-5 放一行、6-9 放另一行,因为 2-5 是 sourceX/Y/Width/Height,6-9 是 destX/Y/Width/Height。这只是自动格式化器无法理解意图的上百个例子之一。再比如我常对齐数字和宽高,或 if 块该单行还是换行、要不要括号——总有例外能让代码更易读,而自动格式化器不懂这些例外。这就是为什么据我所知许多大项目不用自动格式化器,比如 Firefox、Safari、Chrome;有些地方自动格式化会让代码可读性差得多。甚至 Flutter 团队也不用。

    greggman3查看英文原文

    AFAIK no formatting can understand intent. Example. I want my canvas.drawImage calls that take 9 arguments to be formatted with arguments 2-5 on one line, and 6-9 on another line because 2-5 are sourceX, sourceY, sourceWidth, sourceHeight, and 6-9 are destX, destY, destWidth, destHeight. That's just one example of 100s where an auto formatter can not figure out intent. Another example, I often align numbers and width and height // convert from screen coords to clip space clipX = mouseX / screenWidth * 2 - 1 clipY = mouseY / screenHeight * -2 + 1 Another example would be how to format an if block. Depending on your style guide if (cond) single-statement might be ok. Or maybe you want them on different lines. Or maybe you require brackets. Or maybe you don't. But there will almost ways be some place in the code where an exception to your style guide makes the code more readable. Auto formatters don't understand those exceptions. This is why AFAIK many major projects do NOT use an auto-formatter. Firefox, Safari, Chrome for example. Because there are places where an auto-formatter will make the code far less readable. They'll give the advice that you are free to run an auto-formatter on your own changes but adding an automated one is a no-go. Even the Flutter team does not use an auto-formatter https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#formatting

    历次讨论

    同类还值得读

    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

    关注向阳乔木

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

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

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