为什么语言文档仍然如此糟糕?

文摘   2024-09-22 14:13   北京  

说真的,这有什么好理由吗?我感觉自己快疯了,因为我看过的几乎每种语言文档都在很多明显的方面糟糕透顶。经常可以看到由单个人更新的第三方库的文档,其结构更好、更全面、布局更好,比语言团队自己维护的官方文档还要好。

我能感觉到吐槽的冲动像绿魔面具一样在召唤我,但为了简洁起见,在我开始之前,让我先列出一些指导原则。如果你的语言文档没有以下特性,你应该_非常认真地_考虑重写它们:

  • 为真实的人类编写的规范语言文档(真希望我不必包括这一点)
  • 文档本身应该有版本控制,这样你就不必筛选那些不适用于你关心的版本的信息
  • 包含语言规范(语法、运算符优先级、关键字等)的参考部分
  • 每个标准库类或内置类型都有单独的页面
    • 类和方法描述应至少回答以下2个问题,最好是全部3个问题:这个做什么(效果)?它是如何做的(内部实现)?为什么我想要它(用例、与类似方法的比较等)?
      • 直接链接到内部实现的源代码。如果你的语言实现是闭源的,你应该感到羞耻。
    • 该页面必须尽可能简洁
    • 该页面必须_包含_(而不是链接到)该类可以调用的每个方法,以及这些方法的描述,最好包括所有继承的函数。
      • 大多数方法应该至少有1个示例
      • 应该有一个侧边栏或等效的东西,包含所有方法名称_按字母顺序排列_,方便搜索和跳转
    • 代码示例应该至少有轻度的语法高亮
    • 示例、描述和函数签名应尽可能多地进行内部链接
    • 非晦涩的名称,或者至少告诉我你的 8字节缩写[1] 是什么意思
  • 最好在一个公开访问的网站上,采用不会让我眼睛流血的样式(暗色模式选项),并且至少能适当响应全屏(16:9)和半屏(8:9)两种尺寸
  • 一个不仅仅是 lmgtfy[2] 的搜索功能???我们是认真的吗???

好吧,显然我再也无法抑制吐槽的冲动了。阅读风险自负。

说真的,cppreference在使用搜索框时直接把你带到duckduckgo是_太糟糕了_。我简直不敢相信它还是这样工作的。_你现在正在阅读的博客_有 客户端搜索[3] ,而我只是个普通人。这并不是说我自己编写了搜索功能,而是如果我能发现它的存在并将其嵌入到我的网站中,他们也应该能够做到。

直接复制Rust

拜托了。

我不在乎你有多讨厌这门语言或拒绝学习它,你必须承认Rust在开发者体验方面付出了_很多_努力。这是我尝试过的唯一一个整个生态系统感觉现代化并尊重我时间的语言。几乎所有其他语言都有 配置地狱[4] ,或 糟糕的包管理器[5] (或根本没有包管理器),或 缓慢/几乎不能工作/令人困惑的IDE插件[6] ,或不存在的新手引导,或者...看,我对这个有很多看法。不过我会尽量保持在主题上。

看看这个:

哇,看起来相当不错。看看那优雅的左对齐、宽度受限的主文本。看看垂直空白的巧妙使用。看看清晰的标题和舒适的文字大小。看看那个视觉上独特的侧边栏,从不分散主体文本的注意力。看看那些经过精心选择的字体颜色 - 纯文本使用高对比度的近白色,不太重要的"stable since"版本号使用低对比度的灰色,链接使用鲜艳的橙色,代码链接使用较深的背景。当直接链接到 页面的某个部分[7] 时,甚至还有一个漂亮的高亮显示

我不是前端专家;也许这并不那么令人印象深刻。在我见过的恐怖之后,这看起来像艺术品。

但它是否也能_正确调整大小_?在2024年?你打赌它可以。

"好吧,但我不喜欢这个配色方案,"你可能会说,"它不难看,但对我来说有点暗/亮"

别担心,有一个完整的_选项菜单_,提供比默认主题更亮和更暗的主题

看看标准库描述中有多少链接。还有隐藏的额外链接。点击右上角的logo会从文档的任何位置带你回到这个根页面。让我们点击Vec<T>的链接看看:

查看方法本身时会变得更好

看看这个_细节_水平。Rust文档中的所有内容都是这样的,我几乎从不带着疑问离开。即使我有疑问,眼尖的你可能已经注意到右上角的"Source"按钮。点击它会带我们到这个页面:

这是...这是直接从文档链接的.drain的_源代码_,并且可以离线使用吗?即使文档对内部工作原理不够具体,我也可以只需一次点击就去_查看_它们是如何内部工作的?绝对令人难以置信。我唯一的抱怨是,这是文档中唯一一个不能正确处理半宽的部分。

总之,让我们谈谈搜索。我相信你看到了上面的框。在我们试用之前,我想指出这不仅仅是"搜索",而是_带有便利功能的搜索_:

我的_天啊_。

让我们试试搜索:

  • 开箱即用™
  • 按crate过滤
  • 按名称、按具有该类型参数的函数以及按返回该类型的函数搜索结果
  • 不会重定向你到DUCKDUCKGO

总结:Rust文档非常接近完美。

想知道最精彩的部分吗?上传到Rust包管理器的每个库都有_一个这样的自动生成的网站,包含库中所有的文档注释_。

甚至还有一个_额外的下拉菜单,用于crate元数据和访问旧版本的文档_

_这_就是我说Rust感觉像现代编程时的意思。你通常不关心的东西是不显眼的,有低对比度的颜色,或者以其他方式隐藏起来。你确实关心的东西是明显的、方便的、描述性的、易于阅读的和可定制的。这些都不应该是革命性的。

拥有我喜欢阅读的文档并非不可能。不幸的是,行业标准似乎介于"彻底令人反感"和"有一些明显缺陷"之间。

耻辱名人堂

这并不是要面面俱到。它包括我使用过的语言,以及Java和Go作为"对照组"。值得一提的是,我还花了一些时间研究了Zig、Odin、PHP、OCaml和Ruby的文档,发现它们都有类似的问题。

Python

Python没有为其内置类型提供单独的页面,因此在Google搜索float文档时不会导向Python文档:

除非你向下滚动,会提供一个链接到固有浮点限制和CPython内部float表示的页面。这两者都不会告诉你可以在float上调用哪些方法。

与Rust形成对比:

前3个链接是官方文档,一个用于每种位宽的float,另一个链接到更非正式地描述Rust内置数据类型的Rust入门书籍。Python_确实_有一个 等效的页面_部分_[8] ,但当你搜索"python float"时它不会出现,因为它将intfloatcomplex放在一起,这使SEO变成了SE-No(抱歉)。此外,该页面上intfloatcomplex的链接并不链接到类文档,而是链接到内置的类型转换函数。为什么。

大多数文档都是这样布局的,这使得找到任何东西都变得非常痛苦。你需要不断思考"这可能与什么其他相关的东西分在一组"而不是直接寻找你想要的东西。这最终并没有太多降低内部搜索性能,但内部搜索本身也有一些问题。它会取整个标题并按字母顺序排序,所以最终会得到一些不直观的结果,比如较短的完全匹配dict实际上应该排在ast.dict之上:

Python也不努力解释大多数方法的内部实现或语义。对于像Python这样的语言来说,这是可以理解的,但我确实记得有很多挫折和查看CPython源代码的经历。对我来说,CPython中用Python编写的部分(即大部分标准库)不链接到源代码似乎也很愚蠢。

C#

嘿,看,一个无法正确处理两种窗口大小的网站。在半宽视图中,(相当糟糕的)导航窗格完全消失了。我稍后会讲到。左上角的汉堡菜单打开了整个网站的导航菜单,这是无用的。右上角的小小的3点菜单打开了人们真正想要的导航窗格,但只有在额外点击"目录"之后才会打开,因为为什么要让它变得容易或方便呢。

哦,天哪,目录菜单。恶心

为什么它加载时我所在的模块会滚动到屏幕中间?为什么要包含其他模块?这迫使他们嵌套菜单,使其更难阅读。如果我想要其他模块中的东西,我会去其他模块的页面(假设从一个集中位置或搜索功能很容易到达那里)。此外,我所在模块的所有展开项默认都是最小化的,需要更多点击才能找到我要找的东西。

这还不是全部 - 你注意到有_两个_搜索图标吗?一个在目录中,另一个在主页上。我要查找add,因为我想知道如何使用List方法让我把东西放入列表中。这是使用主页搜索的结果:

嗯...这看起来很可疑,像是 cppreference 的 DuckDuckGo 重定向,但更加微妙。它显然还是在微软的页面上,但看起来他们似乎从真正的搜索引擎抓取了搜索结果,只提取了来自他们 URL 的结果,然后粘贴到搜索结果中。唯一能让这更可能的是,如果微软拥有并运营一个旨在与 Google 和 DuckDuckGo 等竞争的搜索引擎...

此外,这些结果很奇怪。它们没有以任何可辨别的方式排序或过滤,也没有排序选项。我是从 /dotnet/api/ 内的页面运行这个搜索的,但第一页的一些结果来自 /powershell//javascript/ 部分。我完全不介意它们出现在那里,但它们应该排在列表的更下面,或者默认情况下过滤器应该设置为只显示来自 /dotnet/ 部分的结果,当我从 /dotnet/ 部分搜索时。

目录搜索要糟糕得多。我再次从 system.collections.generic.list 页面搜索 add:

所以我猜我们只是在完全匹配之前填充部分匹配?很奇怪。但是...等等...我向下滚动整个列表,List.Add 不在其中。我们是认真的吗?我们不优先考虑我已经在的页面上的内容吗?

好吧,没关系。Rust 文档也不这么做。那让我们搜索 List.Add:

...

叹气

是的,搜索方法时你必须包含 <T>。最令人困惑的部分是,他们已经付出努力允许在泛型位置使用任何东西

但是你不能在多个泛型参数之间添加空格

然而没有人认为这是一个问题,甚至没有想到"嘿,也许我们也应该匹配那些没有泛型的东西,为了方便起见"。

别担心,我还没有说完 C#。检查结构体是一场噩梦。为什么没有静态和常量成员的单独部分?为什么它们被归类到字段中?如果有人忘记提到某些东西是常量,现在人们试图修改它并感到困惑怎么办?

这些简短的描述通常只是重述函数的名称,因此毫无意义。此外,你真的没有更好的方法来表示重载函数,除了让它们看起来像一个完全独特的函数条目?

点击这些函数中的任何一个甚至会将你发送到包含所有重载的同一页面。这些页面是由不同的人制作的,他们没有相互沟通或根本没有查看最终产品吗?

哦,对了,关于那些函数签名还有一件事。你注意到它们不包括返回类型吗?甚至没有区分返回<值>的方法和根本不返回任何内容的方法。我不明白这是怎么发生的。他们忘记了吗?是不是有什么东西坏了而没人注意到?为什么我必须点击到一个新的网页并查看函数声明的代码片段才能知道返回类型是什么?

无论如何,即使你到达了方法页面,文档也是极其不一致的。有些非常出色和详细,有些则让你挠头。他们自己 API 的官方描述标题为"备注"。虽然这确实很搞笑,但它有点暴露了他们觉得应该投入多少努力。

我可以继续谈论 C# 几个小时,但我最后给你一件事:

你呃...也许想把它放在像表格或项目符号列表或网格之类的东西中?也许在排序时忽略泛型?据我所知,我不是 CSV 解析器。另外,为什么每个逗号前面都有一个空格?

Java

作为一个从未写过任何 Java 的人,Java 的文档出人意料地难以找到。也许我只是太笨了,但搜索"java api docs"把 Java 8 放在列表的顶部,然后是 Java SE 7 和 SE 19。作为参考,Java 的当前最新版本是呃...让我查阅一下发布矩阵...

当我看到这个时,我忍不住大笑起来。它看起来像是故意设计成尽可能令人困惑的。我无法决定哪个糟糕的特征是我最喜欢的。

  • 两个轴上都有日期
  • 表格不会根据窗口大小调整,但蓝色顶部横幅会调整,所以如果你向右滚动,顶部就会有可悲的空白
  • "我最喜欢的月份是 JDK 21(粗体)"
  • 名为"月份"的列,包含的不仅仅是月份。如果只有一个词可以表示月份和年份。也许我以后会想到。
  • 垂直分隔线?不,那是填充的作用。等等,也没有填充?
  • "过去 5 年",其第一个子标题是"计划"(包含 2 个未来年份)
    • 还链接到一个单独的页面,上面有一个更大、更丑的表格
  • 列表视图"按钮",带你到一个同样糟糕的页面
    • 包含一个"按月查看""按钮",带你回到矩阵页面。为什么不叫它"表格视图"或"矩阵视图"?
    • 在这种情况下,"CPU"是什么意思?"Feature 23"是什么意思?
    • 发布类型/支持时间线/命名方案在底部,在这个巨大的列表下面,但你没有目录,所以没人会知道它存在,而且没有标题链接,所以如果你想向别人展示,你必须说"是的,继续向下滚动大约 15 年,它肯定在那里"

但无论如何,我能够找到一个中心页面,其中有 Java SE/ME/EE 文档的链接。除了点击 SE、ME 和 EE 的"文档"链接不会带你到 API 文档。每个变体都有一个"登陆页面",每个页面的布局都完全不同,出于某种原因,点击那里的链接才会带你到 API 文档。天哪。

无论如何,一旦我们最终到达当前的文档(我想是 Java 22?),在全宽度下它几乎无法阅读,因为文本非常小,而且没有宽度限制。太棒了。

嘿等等,如果 Java SE 不一定实现 JDK 的所有内容,为什么 JDK 没有自己的文档页面用于 JDK?有点像 Rust 如何将 corestd 分开。

它确实可以正确调整大小,并表明如果他们只是限制页面宽度,它就不会那么难以阅读。

另外,当你浏览页面时,你注意到"file system provider"这个文本是一个链接吗?我当然没有。也许只是我的显示器,但那种蓝色与那么小的字体在那么亮的背景上并不足以与...等等,他们的默认字体颜色甚至不是黑色?它是 #474747。那是一种中灰色。我们能不能停止这样做?黑色文本有什么问题?

无论如何,链接在悬停时会变成橙色,但谁在乎呢。这不是 90 年代的冒险游戏,我不是在像素搜寻你的链接。

语法高亮?从未听说过。

为什么这些导航栏按钮有时不是按钮?如果它们不适用,它们不应该根本不存在,或者也许变灰或其他什么吗?点击 Class 将其视为文本,但 Use 显然是一个按钮

但是嘿,至少他们的搜索功能不是侮辱性的。

C/C++

也许挑剔 cppreference 不太公平,因为它不是"官方"文档,但这是每个人都告诉你去的地方,所以算了。一开始就很糟糕。我一点也不惊讶地滚动到页面底部看到 MediaWiki 标志。

几个第一印象:

  • 哎呀我的眼睛
  • 让我拿出显微镜来看这个文本(那些子标题高 9px。。什么鬼。)
  • 行高是不是设置为负值了?为什么所有东西都挤在一起?
  • 完全没有侧边栏导航
  • 东西是有组织的,但看起来是以一种相当随意的方式排序的
  • 是不是因为你试图把所有 C++ 的东西都塞进一个屏幕视图,不显示任何 C 的东西,所以一切都这么小?为什么它像第 11 个脚趾一样挂在那里?

起初我以为它无法正确处理半宽,因为它总是有一个水平滚动条和一些死区。事实证明并非如此。我一直在我的笔记本电脑上写这个,它通过 Windows 使用 125% 缩放选项,因为否则我的任务栏图标的大小适合变形虫。该网站在 100% 缩放时在半宽下工作正常,但在 125% 时不行。我不知道这甚至可能是一个问题。

然而,在 100% 缩放时,有一个小问题。你发现了吗?

好像搜索栏还不够诅咒似的。

我希望我能继续讨论页面的实际内容,但不幸的是,还有一段被破坏的文本我们应该看看。我本想将其隔离,但那样会让它看起来比实际情况更好,所以这里是整个页面。

天哪。这是怎么发生的?那个文本是不是被压碎机压过,侧翻,然后又被另一个稍微强一点的压碎机压过?为什么它看起来像 jpeg 而不是实际的文本?说真的,去网站上自己看看,太疯狂了。使用浏览器缩放不能解决这个问题,文本就像...不知怎么的有错误的宽高比和分辨率?我甚至不知道。

无论如何,示例有点语法高亮,有相当多的内部链接,这很不错。这不是文档的错,但每个定义后面都跟着一个项目符号列表"这里是如何使用这个而不立即破坏一切"是相当有趣的。描述通常相当不错,但当我第一次学习 C 时,我发现示例非常缺乏。

真正的问题是布局。一切都挤在一起。对于表格和标题来说尤其糟糕,它们似乎根本不允许任何填充。这导致了弱的可浏览性,缺少导航栏使它更糟糕。最终浏览页面的最佳方式是使用 ctrl+F。甚至没有标题链接,这是一种遗憾。

当页面内有大量函数(或重载函数)时,情况尤其糟糕。我真的不确定这是间距问题、字体问题、代码格式问题、高亮问题还是其他什么,但当它埋在这种nonsense中时,需要真正的努力和意志力才能阻止我的眼睛在读到一半函数签名时放弃。

Go

Go 是一个褒贬不一的语言。它的布局还可以,有浅色和深色模式,文本颜色可读性不错(虽然浅色主题中的浅灰色可以再深一点)。它可以正确调整大小 - 不过我更希望全宽视图的宽度是有限制的,并且子模块名称与其描述之间的空间少一些。它有(基本可用的)搜索功能,每个页面上的内容都组织得很好。

我对 Go 的主要问题来自于他们自己的文档系统。虽然我很欣赏这种自信,但我确实认为标准库有点特殊,应该与<非谷歌>制作的东西分开。页面顶部还有很多对语言标准库来说毫无意义的元数据。

我们再次遇到了轻微的搜索问题。自己使用自己的系统意味着搜索结果会包含整个 Go 包数据库中的内容,即使你只关心标准库中的内容。这可以通过优先显示你当前所在页面的结果来部分解决,但实际上它应该在 Go 网站上有自己单独的子域名。

更大的问题是 Go 犯了和 Python 一样的错误,把所有内置类型都放在一个页面上,破坏了他们的搜索引擎优化。我花了一分钟才意识到 Map 是一个内置类型,因此没有和其他标准库一起记录。Rust 没有这个问题,因为他们的文档与其他人得到的文档略有不同。特别是,在 Rust 中没有任何类型被认为是"特殊的"。所有内置类型的文档与标准库中的文档完全相同,并且可以从同一个页面访问。这不仅更容易手动查找,还确保了一致性并提高了搜索性能(内部搜索和通过搜索引擎)。如果标准库文档链接到指定 Map 的地方,这可能就不会那么糟糕,但它就是没有。

哦对了,那不是语法高亮,那些类型之所以是蓝色的只是因为它们是链接。可展开的示例甚至更糟。几十行白底灰字的文本。甚至连行号都没有。虽然你可以修改它们、格式化它们并在浏览器中运行它们很酷,但我不确定谁会想这么做,因为它看起来就是那个样子。

总之,在谷歌搜索的第一页或第二页上都找不到 map 类型的文档。我不会再往下找了,因为大多数人不会找到那么远。

通过手动浏览 Go 主页,我找到了描述 内置类型[9] 的语言规范。

我收回之前说布局还可以的话。没有侧边栏,没有搜索功能(除了 Ctrl+F),一个巨大的、几乎没有格式化的标题列表,同时延伸到屏幕外_并且_留下一堆空白空间。真难看。

不过总的来说,我真的没有太多可抱怨的。Go 遵循了许多现代语言的趋势,拥有简单而可靠的文档,但也有一些主要缺陷(例如 Zig、Odin)。

Javascript

Javascript 加入了 C/C++ 阵营,没有官方的、供人类阅读的文档。很好。这让我只能谈论 MDN 了。值得注意的是,我是通过隐身窗口浏览所有这些内容的,所以我的扩展都没有启用。我有点惊讶这个问题直到现在才出现,但呃...

第一印象相当糟糕。我知道 Mozilla 必须以某种方式赚钱,但在语言文档上放广告?哎。如果你一直滚动到底部,还会有另一个横幅。

描述 MDN 的最好方式是"浪费空间"。顶部有三个单独的栏有点太多了,不过顶部的广告在滚动时确实会消失,这一点值得庆幸。Rust 和 Python 的文档给人感觉是宽度适度的,而 MDN 则给人一种拥挤和繁忙的感觉。大字体(16px 对比 Rust 和 Python 的 14px)和窄小的主文章使得每行长度极短。文本最终变得难以解析,很容易被周围的元素"分散注意力"。居中而不是左对齐加剧了这个问题,半宽视图清楚地表明,只要去掉左侧的空白,情况就会好得多。不过,这确实带来了另一个小问题。

叹气 当然,你会用广告挡住一半的侧边栏。

这在其他文档中也是一个问题,但我想在这里指出来,因为这是一个如此明显的案例。为什么搜索功能要隐藏在汉堡菜单里?顶部栏有 700 像素的宽度完全没有用。我在文档中经常搜索东西。把搜索栏放在汉堡菜单旁边就行了。

除此之外,MDN 还不错。文档经常链接,有不错的例子(包括明确标记的通过失败的例子,这很棒!)

代码有语法高亮,搜索和侧边栏过滤器都工作得不错。

它只是一个网站

对我来说,这才是关键 - 既是我无法相信它仍然是这个样子的原因,也是我一开始要说这些的原因。HTML 和 CSS 很容易改变。不需要一门新语言就能有新的文档,甚至不需要一个主要的新语言版本就能美化现有的文档。如果我要花三分之一的生命盯着这些愚蠢的页面,如果它们是为了阅读和导航而设计的,而不是我们现在看到的这样,那将会有很大帮助。

参考链接

  1. 8字节缩写: https://stackoverflow.com/questions/7448262/why-are-c-names-shortened
  2. lmgtfy: https://letmegooglethat.com/?q=lmgtfy
  3. 客户端搜索: https://walnut356.github.io/search/
  4. 配置地狱: https://cmake.org/
  5. 糟糕的包管理器: https://pypi.org/project/pip/
  6. 缓慢/几乎不能工作/令人困惑的IDE插件: https://old.reddit.com/r/vscode/comments/1856p4b/which_c_extension_should_i_choose_cc_or_clangd/
  7. 页面的某个部分: https://doc.rust-lang.org/std/index.html#contributing-changes-to-the-documentation
  8. 等效的页面_部分_: https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex
  9. 内置类型: https://go.dev/ref/spec#Map_types

幻想发生器
图解技术本质
 最新文章