HN 写作课

工程师们二十年里聊过的写作。

工程师、作家、编辑和创业者在 Hacker News 上聊了二十年“怎么写”:怎么写得清楚、怎么讲好一个故事、技术文档怎么写、小说和出版是怎么回事。这里把其中关于写作与讲故事的帖子挑出来,配上中文导读、可以直接用的写作要点和评论翻译。

从必读开始
  • 2,600+篇关于写作的 HN 讨论

Writing tips

写作锦囊

正在抽一条写作要点…

Essential

必读 30 篇

在讨论库里看全部精选

编辑精选里 HN 讨论最热的 30 篇,每篇都有中文导读和写作要点。

  1. 正在载入…

Archive

讨论库

按发帖年份分布,点柱子筛选。

排序

    About

    这些讨论是怎么挑出来的

    1. 01

      从全量里捞

      读取 Hacker News 自 2006 年以来的全部帖子,用关键词先捞出 40 分以上、可能和写作有关的约 1.1 万篇。

    2. 02

      只留真正讲写作的

      由 AI 逐条判断是否和写作、讲故事、文风、出版有实质关系,剔除“写代码”“编辑器”这类字面撞车,并分进十个类别。

    3. 03

      提炼可用的要点

      为值得读的帖子写中文导读,提炼 2-4 条可以直接用到自己写作里的要点,并精选翻译 HN 高赞评论。内容由 AI 生成,可能有误。

    技术写作与文档2016russbishop.net

    用通俗英语解释 Functors、Applicatives 和 Monads

    Functors, Applicatives, and Monads in Plain English

    阅读原文 HN 讨论
    136HN 得分
    62条评论
    4条写作要点

    导读

    这篇文章尝试用大白话和“容器”类比解释函数式编程中的 Functor(函子)、Applicative(应用函子)和 Monad(单子)。对写作者的价值在于,它暴露了一个典型难题:如何把抽象概念写得既不失真、又能让初学者入门;评论区围绕“简化是否可能”提供了很实用的反思。

    关键词 抽象概念解释技术写作类比简化

    可以直接用的写作要点

    1. 01

      解释抽象概念时,抽象定义和具体例子要并进:只讲定义,读者不知道为何要在意;只讲例子,读者又看不到共性。

    2. 02

      类比要能落地:像“容器/map/flatMap”这样的比喻应配上可操作例子,并交代它省略了什么。

    3. 03

      别怕简化被专家挑刺;写作目标是让读者入门,但可在文中标明简化边界,避免把“半懂”当成“全懂”。

    4. 04

      把“理解需要实践”写进文章:用乐理等类比提醒读者,概念要在实际读代码、写代码中反复对照才真正有用。

    HN 评论精选

    社区常把“简化”当成错误来纠正;写作者要接受专家批评,但别放弃为读者简化。

    我发现,在编程社区里试图把东西简化是不可能的(总会有人说“你没抓住重点/你过度简化/这根本不是 monad”)。这个问题源于周围有太多人过度自豪于属于一个天才精英群体。我常这样描述程序员:“程序员是喜欢创造比喻的人,但更喜欢纠正别人的比喻的人。”不过,读这篇文章让我对这些概念的理解有进步,所以谢谢作者。

    VeejayRampay查看英文原文

    I've found that trying to simplify things is an impossible thing to do in the programming community (cue to "You're missing the point / You're oversimplifying / This is not what a monad is"). It's a problem that stems from being surrounded by millions of people who take disproportionate pride in the belonging to a savant elite. What I always say to people who ask me to describe programmers: "Programmers are people who like to create metaphors, but who like to correct other people's metaphors even more". That being said, I feel like I've progressed in my understanding of those concepts by reading the post, so thanks to the author.

    抽象概念教学要在抽象与具体之间来回,真正的理解来自实践;类比乐理说明“先做再懂”。

    写了成千上万篇博客后,我觉得下面几点仍未改变:只抽象解释这些概念,读者会困惑为什么要在意这些没用的抽象概念;只解释具体实例,又会错过它们都是同一概念实例、以及可在这一层写可复用代码这一要点;唯一同时理解两层的办法是坐下来读/写大量代码,直到两层都懂。过了这关你就懂了,但再想找捷径解释给别人时又会撞上上面两个障碍。这让我想到乐理:你可以灌一堆音阶、调式、和弦概念,但在真正玩一阵音乐之前全是废话,之后大部分概念才既好懂又有用。

    wrs查看英文原文

    Thousands of blog posts later, I don't think the following has changed: * Explaining these concepts in the abstract results in bafflement as to why anyone would care about these useless abstract concepts. * Explaining only the concrete instances of these concepts results in missing the point that they are all instances of the same concepts (and that you can write reusable code at that level, which can be a big productivity improvement). * The only way to understand both at once is to sit down and read/write a bunch of code until you understand both levels. And once you pass that point you get it, but then you hit the above two roadblocks trying to find a shortcut to explain the concepts to someone else. It reminds me of music theory, where you can bombard someone with all sorts of concepts like scales, modes, chords, etc., but it's all nonsense until they actually play music for a while--then most of it is both understandable and useful.

    “大白话”类比背后仍是形式定义;写作时若省略关键操作(如 pure),类比会不完整。

    他所谓的“大白话”描述其实基本就是 Haskell 的定义。Haskell 为了效率多定义了一两个方法,但忽略默认实现后就是:1)Functor 是能调用 map 的容器,就这样。fmap (+2) [5] = [7]。历史上 Haskell 的 fmap 曾叫 map,改名是为了列表相关错误信息不那么抽象。2)Applicative 是容器里放函数并应用到同类型容器里的值:pure 5 = [5];[(+2)] <*> [5] = [7]。作者描述了顺序应用操作符,却漏了把纯值提升到容器。3)Monad 是能调用 flatMap 的容器:[1,2] >>= (\x -> [x + 5, x + 10]) 得到 [6,11,7,12],即 [1+5, 1+10, 2+5, 2+10]。

    MichaelBurge查看英文原文

    His 'plain english' descriptions are really just the definition in Haskell. Haskell defines one or two more methods for efficiency, but if you ignore the entries with default implementations you get: 1. "Functors are containers you can call map on. That's it. Seriously." class Functor f where fmap :: (a -> b) -> f a -> f b Historically, fmap in Haskell used to be called map. They gave it a different name so that error messages would appear less abstract when working with lists. fmap (+2) [5] = [7] 2. "you may want to have a function in the container and apply it to value(s) in another container of the same kind. " class Functor f => Applicative f where -- | Lift a value. pure :: a -> f a -- | Sequential application. (<*>) :: f (a -> b) -> f a -> f b So at least in Haskell, he describes the sequential application operator but leaves out the ability to lift a pure value to a container value. pure 5 = [5] [(+2)] <*> [5] = [7] 3. "Monads are containers you can call flatMap on. Again, that's it." class Applicative m => Monad m where -- | Sequentially compose two actions, passing any value produced -- by the first as an argument to the second. (>>=) :: forall a b. m a -> (a -> m b) -> m b And here's how to use it like a flatmap: [1,2] >>= (\x -> [x + 5, x + 10]) [6,11,7,12] That's [1 + 5, 1 + 10, 2 + 5, 2 + 10] if you didn't catch that. Usually these also come with some laws to help you reason about the typeclass, but looking purely at the language level it can help to remember that a Functor, Applicative, or Monad are nothing more than a type together with some functions with a certain signature. I find it's usually more useful for a beginner to just start writing code without all the abstractions. Once they have a pile of code and start to want to clean it up a bit, it's not too hard to start stacking some monad transformers.

    半懂抽象概念几乎无用;要么学会具体接口,要么深入数学/范畴论,容器类比不足以解释全貌。

    作为一个走过这条路的人——从函数式编程完全外行,靠本文这类简单例子学习,到最后终于开始 grasp 范畴论基础——我可以说,实际数学视角无可替代。文章讨论的概念很抽象,使“半懂”很难有用。初学者读完文章就去用这些概念,几乎不可能。要么你学会现有接口(如 Maybe monad、Reader monad)并会调用,要么你对 Monad 作为概念有扎实把握、能用于任何语言(通常意味着懂点范畴论)。只知道“Monad 是返回扁平化容器的容器”没用。也就是说,用 Monad 不必懂 Monad;而若想真正懂,容器类比可能太粗浅,无法让你看到它为何有用。

    proc0查看英文原文

    As someone who has walked that path, being a complete beginner in functional programming, learning via simple examples, such as the article, and then finally learning (or perhaps beginning to grasp) the basics of category theory, I can say that from my observation there's no substitution to the actual mathematical perspective on the matter. This point might have been made elsewhere, but I think the abstract nature of such concepts discussed in the article, makes it hard for "partial understanding" to be useful. In other words, for a beginner to read the article, and then go and start using the concepts themselves, is very unlikely. Either you learn the existing interface like the Maybe monad, or the Reader monad, and you learn how to invoke its functionality, OR you have a solid grasp of Monads as a concept and how it can be applied in any language, which usually means some understanding of category theory. To JUST know that Monads are containers that return "flattened" containers is useless. In other words, you don't need to understand Monads to use them, and if you want to understand them, then perhaps containers are a bit too bastardizing to give you a full view of how and why they're a useful pattern.

    同类还值得读

    1. 编写更好文档的框架

      A Framework for Writing Better Documentation

      这是 Divio 的文档写作框架,把技术文档按「读者的目标」分成四类:教程(学习导向)、操作指南(问题导向)、参考(信息导向)、解释(理解导向)。

      技术写作与文档2021 · 637 分 · 76 评4 条写作要点编辑精选
    2. 写好一份设计文档

      Writing a good design document

      这篇 HN 帖子标题为《Writing a good design document》,主题是如何写好一份设计文档;对写作者来说,它值得作为技术写作和结构化说明文的参照。

      技术写作与文档2025 · 581 分 · 147 评3 条写作要点编辑精选
    3. 技术写作课程

      Technical Writing Courses

      这是 Google 官方免费技术写作课程(两门),讲受众定义、主动语态、短句、文档结构等基础方法。

      技术写作与文档2020 · 571 分 · 73 评4 条写作要点编辑精选
    4. 写出更好的错误信息

      Write better error messages

      这篇帖子讨论如何写出更好的错误信息,评论补充了开发者场景下的具体做法和真实反面案例。

      技术写作与文档2022 · 566 分 · 253 评4 条写作要点编辑精选
    5. 写一本技术书的经济账

      The Economics of Writing a Technical Book

      一位技术书作者拆解写书的真实经济账:版税收入往往远低于投入的时间成本。

      技术写作与文档2018 · 519 分 · 149 评4 条写作要点编辑精选

    打赏支持

    打赏二维码

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

    WeChat

    关注向阳乔木

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

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

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