今天的博客将会做一期比较偏门的程序构建方法literate programming.
以下是wiki针对文式编程的概要说明:
文式编程是Donald Knuth提出的一种编程范式,在这种编程范式中,计算机程序以自然语言(如英语)解释其逻辑,中间穿插着一些宏片段和传统的源代码,从中可以生成可编译的源代码
Knuth所构想的文式编程范式,代表着从以计算机所规定的方式和顺序编写计算机程序的转变,而是使程序员能够按照逻辑和思想流所要求的顺序开发程序。
[2]文式程序是作为对逻辑的不间断的阐述而编写的在一种普通的人类语言中,很像一篇文章的文本,其中包含宏来隐藏抽象和传统的源代码。
文式编程(LP)工具用于从文式源文件获取两种表示形式:
一种适合计算机进一步编译或执行,“编织”代码,
另一种用于查看格式化文档,据说这是由有文化信息的源代码编织而成的。
[3]虽然第一代有文化信息的编程工具是特定于计算机语言的,但后一代工具与语言无关,存在于编程语言之上。
首先以开源的文式编程工具lit为例子来说明其工作原理
文式编程是一种写程序的方式,优先理解。所有的文学程序都包括散文和文学结构。例如,本段是一个有效的识字程序。
读写工具接受一个读写文件,并基本上生成两种类型的文件。首先,它们生成计算机能够理解的源代码。因为有读写能力的程序本质上是易读的,所以这些工具通常会生成很好的文档。
程序必须为人们阅读而编写,并且只能为机器执行而附带编写。
-H、 Abelson和G.Sussman(SICP)
lit有几个显著特点:
所有的散文都可以用标记或明文来表达
支持所有编程语言
缩进定义的识字结构
可以监视文件或目录的更改,自动重新编译
例子
下面是一个示例文件helloWorld.hs.lit/
这里是一个完整的haskell "hello world"程序
我们将定义”*“ 作为所有程序的宏
<< * >>=
<< a trivial comment >>
<< print a string >>
现在我们可以定义上面的每个宏,
从无关紧要的评论开始!
<< a trivial comment >>=
-- this is a hello world haskell program
最后我们通过程序打印出"Hello, World!"
<< print a string >>=
main = putStr "Hello, World!"
lit可以通过多种方式处理可读文件。要简单地生成代码文件,请运行:
$lit -c helloWorld.hs.lit
语法
lit只有两个有效结构:
宏定义:<<…>>=和宏引用:<<…>>
任何共享行或初始缩进右侧的行都包含在定义中。宏定义是放置实际源代码的位置。它还可以包含宏引用。
也可以通过稍后在可读取文件中创建同名的宏定义来扩展宏定义。
当lit试图从可读文件生成源代码时,它会使用相应的宏定义扩展每个宏引用。按照惯例,lit从根宏定义<<*>>=开始,生成源代码时必须包含根宏定义。
它生成文件helloWorld.hs
好了,上面的简单例子说明结束后,让我们进入今天的主题:
nbdev是一个库,允许您在Jupyter笔记本中完全开发一个库,将所有代码、测试和文档放在一个地方。那就是:你现在有了一个真正有文化的编程环境,就像唐纳德·克努特在1983年所设想的那样!
使用交互式环境,您可以轻松地调试和重构代码。将导出标志添加到定义要包含在python模块中的函数的单元格中。例如,这里是如何在fastai库中定义和记录组合的cos:
使用这样编写的笔记本,nbdev可以用一个命令创建和运行以下任何一个:
- 可搜索的,超链接的文档;任何你用反勾号包围的单词都会自动超链接到相应的文档
- Python模块,遵循最佳实践,例如使用导出的函数、类和变量自动定义所有(更多详细信息)
- Pip安装程序(为您上传到pypi)
- 测试(直接在笔记本中定义,并并行运行)
- 在标准文本编辑器或IDE中导航和编辑代码,并将所有更改自动导出回笔记本
- 由于您在笔记本中,还可以添加图表、文本、链接、图像、视频等,这些内容将自动包含在库的文档中。定义代码的单元格将被隐藏,并替换为函数的标准化文档,显示其名称、参数、docstring和到github上源代码的链接。例如,上面的单元格转换为:
{%include image.html alt=“nbdev中的文档”caption=“来自fastai库的自动文档示例”max width=“600”file=“/images/doc_example.png”%}
其当前提供以下功能并允许用户针对性开发自己需要的功能:
- 从jupyter笔记本到python库的导出功能
- 可以在终端中与nbdev一起使用的cli命令
- export2html如何为库构建文档
- sync如何允许您从python模块导出回jupyter笔记本
- 在笔记本中放置测试,这些测试可以并行运行,并从笔记本导出到CI环境