浅谈LP

作者: 俞子将 | 来源:发表于2018-05-20 20:21 被阅读165次

    目录

    1.  [源码与文档](#1)
        1.1  [只编码,不写文档](#1.1)
        1.2  [分离的源码和文档](#1.2)
        1.3  [源码中插入文档](#1.3)
        1.4  [文档中插入源码](#1.3)
    2.  [文学编程](#2)
        2.1  [文学编程的好处](#2.1)
        2.2  [常用文学编程工具](#2.2)
    3.  [参考资料](#3)
    

    LP(Literate Programming),即文学编程。它的想法是,构造程序时,我们应该用文学的语言解释代码给人看为主要目的,而不是单单编码给计算机运行。

    在开始正式介绍LP前,我们先谈谈程序员中永恒的话题,编码与文档的关系。

    1. 源码与文档

    程序员对这的态度或行为,大概可以概括为以下几类:

    • 只编码,不写文档
    • 分离的源码和文档
    • 源码中插入文档
    • 文档中插入源码

    这里的文档泛指用来阐释源码的文字,它可能是个独立的文件,也可能是源码中的注释等等。好的文档,能帮助开发者快速地读懂源码也有利于将来的维护。

    1.1 只编码,不写文档

    这类程序员往往以Linus说过的 "Read The F*cking Source Code" 为宗旨(可以称为RTFSC党)。RTFSC党会认为自己写的代码清晰明了、通俗易懂、老少皆宜,完全没有必要再编写文档、注释等等。他们可能会说,我函数名起得这么好、我链式语法写得这么棒、我用promise写异步、我amb求值器设计得这么好,这样的代码你都看不懂?还要我写文档?要你何用?

    虽然大多数程序员都自认为自己的源码写得巧夺天工,但是在别的程序员眼里,往往是又臭又长的存在。当一个程序员看到一段复杂的逻辑而没有一个文档说明,往往杀人的心都有了。甚至,开发者在数月后看自已以前写的代码,如果没有文档,可能自己都看懵逼了。

    下面是摘自 14th国际c语言混乱大赛的代码。只要你愿意,理论上可以把任何代码写成飞机。

    1.2 分离的源码和文档

    这类程序员应该是比较常见的。不管主观愿不愿意,他们除了输出源码文件,还会输出对应的文档文件。要编写文档了,程序员们会创建独立的word文档,或者更有追求的可能会选择创建MarkDown、reST、AsciiDoc、DocBook、OrgMode等标记文档。

    编写文档有可能在编写源码前,也有可能在编写源码后。他们可能在编写源码前,编写好相关的独立的设计文档,再按设计文档来开发代码。也可能在编写源码后,补充文档,用来日后交接工作等。

    文档完成后,与源码文件往往是分开存储的,存不同的目录。在版本管理上,往往会创建不同于源码的文档工程,用来专门保存文档。

    1.3 源码中插入文档

    相比RTFSC,他们往往会在代码中加入大段的注释。函数、类都有规范的写注释方式。往往还有配套工具,支持从源码中抽出这些注释,再生成独立的文档。比如,doxygen、javadoc、appledoc、swagger-ui等。

    这方面做到极致的是,我觉得是swagger-ui。它主要是给后台生成在线接口文档的。通过在java代码中,插入一些格式化的注释,它会生成接口的静态网页文档,并启动web服务加载。而且,你除了看在线接口文档外,你还可以在线填写参数测试接口,它会用curl进行接口请求,并显示结果,简直不要太爽。大家感兴趣可以去看看swagger-ui的demo

    有些程序员还不满足于在源码中插入普通的文本注释,还想在源码中插入流程图、交互图等。但是,源码作为纯文本文件又不能插入图片,于是只能插入ascii art文本图。如果,你给你的复杂源码中插入类似如下这么个流程图,看代码的人肯定会感动得痛哭流涕。

    网上有在线生成ascii art的网站asciiflow。Emacs里也有 AsciiMode、figlet、picture等mode可以画ascii art图。

    1.4 文档中插入源码

    最后一种,是在文档中插入源码。它与上一种在源码中插入文档相同的是,它们的文档和源码都是放在一起的。不同的是,它强调编程应该面向人,应该以提供解释说明为主,而不是为了写出计算机可以识别的程序。

    这就是文学编程的思想,即更主要目的是文学,而不是编程。

    因为是主要是面向文档的,所以这里的文档可以比代码中插入的注释丰富很多。不少文学编程工具,往往提供统一显示文档和代码块的界面。比如,学习python的可能都接触过的jupyter notebook。

    jupyter中可以用markdown来插入图片、链接跳转、数学公式等。同时,其中的代码块也能直接运行,并在文档中插入运行结果(如画图、表格等)。

    还有其他工具环境,类似swift playgroudsorg-mode 也提供了文学编程的能力。特别是org-mode 甚至可以在一个文档里插入多种不同语言的代码块,所以在它里面,你可以用你擅长的不同语言来处理不同的事情。

    2. 文学编程

    Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.
    (Knuth 1984)

    IT界大佬Knuth 认为,构造程序时,我们更多地应该从写作的角度出发,用文学的语言解释代码给人看为主要目的,而不是以编码给计算机运行为目的。

    注: 还有个RR (Reproducible research),可重复性研究,与LP有些相似的概念,可以在文末的参考资料中查看二者的区别。

    文学编程,从写作、文学的角度出发,代码只是以代码块的方式插入到文档中。随后,文学编程工具一般还提供Tangle功能,可以从整个文档中抽出全部代码,也提供Weave功能,可以把文档导出成html、pdf等更通用的文档格式。

    org-mode 为例:

    org-mode 是类似markdown的格式化文本。文档中可以插入图片、表格等元素,并且可以插入 #+begin_src#+end_src 围起来的代码块。org-mode中的代码块可以是任何语言,在org-mode里面执行后可以把输出(图片、表格、raw)等插回文档。它也提供 Tangle 和 Weave功能,对org-mode文档进行代码提取或格式导出。

    2.1 文学编程的好处

    文学编程把描述和代码块放一起,并且代码块可以运行,它提供了以下好处:

    • 科学计算等场景,随时要验证理论是否正确,如果把理论文档和代码块放一起,可以随时验证理论是否正确。
    • 软件开发场景,丰富的文档和代码放一起,更能理解代码实现,也利于以后维护、扩展。
    • 教学场景,往往需要一步步、手把手地写代码(hand in hand)。一个步骤一个解释配一个代码块的方式,学员更容易理解,而且可以自己动手运行代码块尝试。

    2.2 常见的文学编程工具

    下面介绍文学编程的一些比较流行的工具/环境:

    Jupyter notebook

    首先介绍 jupyter notebook

    近年来,随着机器学习 的迅猛发民,越来越多的人用jupyter notebook来做数据分析、课题研究、教学等,大有取代matlibR之势。因为它是以文档为目的的,所以最后可以直接生成报告、演示文档等,非常酷。

    Jupyter notebook 有以下几个很酷的地方:

    • 支持超过40种编程语言,包括Python, R, Julia 和 Scala。它有各种内核如ipython、iswift等。

    • 会起jupyter server,然后用web浏览器进行开发。所以注定,它可以很方便地进行分享。别人也可以简单地用web远程连接到你的jupyter server上,就可以开发了。

    • 跟大部分文学编程工具一样,代码块可以产生丰富的内容,如网页、图片、视频等,再插入到文档中显示。

    • 最后,jupyter抽代码和导出文档功能也很齐全。

    基于b/s设计,也注定了客户端不需要关注开发环境,只需要一个浏览器就够了,更方便重现研究、分享。

    你可以用连接官网的 Try Jupyter 进行jupyter试用。自己安装的话,建议安装conda 全家桶。

    jupyter notebook 中把文档按cell进行组织。cell可以是文档类型,也可以是code类型。

    • 文档类型的cell,走markdown语法。用markdown语法,基本可以写出很丰富多彩的内容了。
    • code部分的cell,和内核相关。如内核用的ipython,那么code部分就当python来解析了。

    jupyter notebook 的代码块部分那么强大,能输出各种格式,这完全依赖于强大的内核功能,如依赖于强大的ipython,它可以输出丰富的网页格式。

    Swift Playgrounds

    学习Swift语法的同学,基本应该都是在Swift Playgrounds中学习。Swift Playgrounds 提供一个swift的非常酷的交互环境,在教学等场景下非常高效。

    可以参照 Swift Playgrounds — Interactive Awesomeness 这边的入门介绍。

    我们可以通过Playing with SpriteKit in a Swift Playground 这个例子来一窥它强大的交互。

    从这个图中可以看出,

    • 它通过markdown展示了如何生成Rainbows的思路。
    • 每行代码在右边生成了当前代码行代码的输出,有点像REPL的交互。
    • 最右边的Assist中的Live View,展示了SpriteKit的运行效果(实际运行时,彩虹会动,同时会有音乐播放)。
    • 最下面的console会输出打印(这个示例中没有打印输出)。

    可以说交互很无敌了,非常酷。

    注: 不过苹果推出的SpriteKit这个游戏库貌似实际开发中没什么人用。

    Org-Mode

    最后压轴出场的是Org-Mode。它是Emacs这个神器中用来写文档的一个major mode。Org-Mode可以用来写GTD、组织文档、文学编程等。

    Org-Mode常见介绍和简单用法可以参考神器中的神器org-mode之入门篇

    Org-Mode中使用文学编程的介绍,可以参考A Multi-Language Computing Environment for Literate Programming and Reproducible Research

    Org-Mode中负责处理代码块的是Org-Babel。它的介绍可以参考Babel: Introduction组织你的意念:Emacs org mode

    之所以叫Babel,可能是因为它被翻译成的语言最多的吧,真正做到了语言无关。另外,Douglas Adams在科幻小说银河系漫游指南中提到的Babel Fish,它是一种可以很小、黄色的可以塞到耳朵里,把一种语言转换成另一种语言的奇怪的鱼。

    下面展示了,在Org-Mode中,使用10种语言打印Hello world!

    当然,Org-Mode中还可以在不同语言中传递数据。每个代码block中也可以设置session,来保证相同的语言多个代码块之间共享环境。

    另外,也有人为Org-Babel开发了对应的ipython版本,我们可以在强大的Org-Mode中使用强大的ipython。(scimax

    3. 参考资料

    1. A Multi-Language Computing Environment for Literate Programming and Reproducible Research

    2. Swift Playgrounds — Interactive Awesomeness

    相关文章

      网友评论

        本文标题:浅谈LP

        本文链接:https://www.haomeiwen.com/subject/wxntjftx.html