我学习的习惯,认真说起来,并不算好。
别人若是沿着一条路走,先定目标,再排计划,按部就班,一日一日往前推进,总能走出一种清楚的样子。我却常常不是这样。一本书读着读着,忽然被脚注带走;一个概念查着查着,又顺着参考文献滑到另一处;一个本来只是辅助用的小工具,也可能引出半天甚至一天的折腾。等到晚上合上电脑,才发现原先要做的正事还停在那里,旁边却多出一堆枝枝蔓蔓的笔记。
若按效率来衡量,这当然有些糟糕。
可是人到后来,也慢慢学会了不太苛责自己。许多看似绕远的路,未必全是浪费。有些知识,当时看不出用处,几年以后忽然在某个地方亮了一下;有些工具,学的时候只觉得好玩,后来竟成了日常里离不开的东西。学习这件事,有时像走山路。地图上看,直路最短;真正走进去,才知道旁边一条小径上,也许有水声,有树影,有一块多年无人坐过的石头。
最近,我本来是在研究 AI 里的大语言模型与知识图谱结合的问题。
这已经不是一件轻松的事。大语言模型本身有一套东西,知识图谱又有另一套来路。一个偏向统计和生成,一个偏向结构和关系;一个像一片广阔的雾,一个像雾里试图立起来的架子。要把两者放在一起看,原本就需要重新读不少材料,理清许多概念。按理说,我应当老老实实守在这条主路上,把论文一篇篇读下去,把问题一个个拆开。
可是,我又分岔了。
事情的起因非常小。读材料读到一半,我觉得不能只在脑子里过一遍,总要记点笔记。记笔记时,又觉得不能只是摘录,最好每学完一个知识点,就写一篇简短的读后感。写读后感时,又忽然生出一个不大合时宜的念头:既然是一篇篇写,总该知道自己已经写了多少篇吧。
知道多少篇,本来很简单。拉到文档里数一数,也不过几秒钟。可这几秒钟,在一个有点老派又有点执拗的程序员心里,便不肯轻易过去。既然是计算机能做的事,为什么要我自己去数?如果每次都手动数,那我这些年自称喜欢程序、喜欢工具、喜欢自动化,岂不是有些说不过去。
于是,一个原本与大语言模型有关的问题,悄悄转向了另一个问题:怎样让我的笔记文档自动计数。
我用的是 org-mode。多年下来,Emacs 像一张旧书桌,桌面并不华丽,抽屉也有些松,可手一伸,大概知道东西在哪里。org 文档自然好用,标题、层级、折叠、链接、代码块,都安安静静在那里。可若要让一个普通文档在写作中自动运行程序,便要牵出 Knuth 教授当年提出的“文学编程”概念。
所谓文学编程,说起来很有趣。它不是把代码和说明分开,像一边是机器,一边是人;而是让程序嵌在叙述里,让人读得懂,也让机器跑得动。代码不只是冰冷的指令,也成了文字里的一部分。这个想法很 Knuth,也很旧派,带着一种精巧而不急躁的手艺气。今天许多工具更时髦,界面更漂亮,可我仍然喜欢这种把文档、思考和程序缝在一起的方式。
不过,喜欢是一回事,会不会又是另一回事。
我用了 Emacs 很多年,却不能理直气壮地说自己会 Emacs Lisp。平时改配置,多半是到处抄一点,查一点,试一点;能跑就行,跑不动再说。真要自己写一个函数,调用 org-mode 的接口,遍历当前标题下的子标题,再把数量插入到当前位置,便忽然发现,原来自己并没有真正懂。
这时,学习的分岔便正式开始了。
我先去查 org-map-entries 怎么用,又去看 org-current-level 返回什么;看了半天,发现还要了解 save-excursion,知道它怎样帮我在文档里移动光标之后再把位置还回来。再往下,又碰到 cl-defun,碰到可选参数,碰到 interactive,碰到 local-set-key。每一个词都不算大,却像路边伸出的一条小岔道。你若不理它,事情也许可以糊弄过去;你若想弄明白,它便会把你领到更深处。
中间自然也有很多笨拙的时刻。
代码第一次运行,没有反应。第二次运行,数字出来了,却不是我想要的层级。第三次运行,位置不对,把数字插到了奇怪的地方。后来又发现,若不限定在当前 subtree 里,整个文档的标题都会被算进去。那一刻,我盯着屏幕,心里有些好笑:我本来是要研究 AI 的,怎么现在竟然在为一个标题计数函数皱眉头。
可是皱眉头归皱眉头,心里并不烦。
这大概就是兴趣和任务的区别。任务若卡住,人会焦躁;兴趣若卡住,人反而有一种轻微的兴奋。像年轻时在实验室里装 Linux,48 张软盘一张一张换,装到半夜两三点,系统报错,屏幕黑着,却仍然不愿意回宿舍。那时并没有想过这些东西将来有什么用,只是觉得好玩。好玩二字,年轻时说得轻,后来才知道,它能支撑一个人走很久。
这一次,也差不多。
查资料,看文档,问 AI,自己改,自己试。差不多折腾了八个小时,最后终于把那几行 Elisp 写出来。代码很短,短到若贴给真正懂 Emacs 的人看,大概只会微微一笑。可是当我在读后感文档里,轻轻按下组合键 `C-c C-h n`,一个数字跳出来,安安静静落在当前行,告诉我已经写了几篇读后感时,我竟然有一点小小的快乐。
;; Counting sub-headings
(cl-defun my/count-org-headings (&optional (level 4))
"计算当前 headings 下指定 sub-headings 的数目.
LEVEL 是一个数字,作为参数提供,默认指定第 4 级"
(interactive "nLevel: ")
(let ((count 0))
(save-excursion
(org-map-entries (lambda () (when (= (org-current-level) level)
(setq count (+ count 1))))
nil 'tree))
(insert (number-to-string count))
(message "Number of level %d subheadings: %d" level count)))
(add-hook 'org-mode-hook
(lambda () (local-set-key (kbd "C-c C-h n")
这种快乐,很难向不喜欢折腾的人解释。
他们也许会说,为了数几篇文章,花八个小时,实在不合算。确实不合算。若只为得到那个数字,当然不值得。可是这八个小时里,我重新理解了 org-mode 的一点结构,摸到了一点 Elisp 的语法,也把文学编程这个旧概念又放回自己的手边。最后得到的,不只是一个数字,而是一段重新进入工具内部的经历。
学习常常如此。
表面上看,是为了某一个结果。真正留下来的,却未必是结果本身。一个学生做题,本来只是为了算出答案;若他在推导中看见某个近似的边界,知道公式在哪些条件下才成立,这就比答案更重要。一个人学 Python,本来只是为了处理一张表;若他因此懂得数据怎样读入、清洗、检查、可视化,便已经多学了许多。一个读书人查一个典故,本来只是为了确认一句话的出处;若他顺着出处读到上下文,知道这句话原来并不是今天人们常用的意思,这一点绕路,也就没有白走。
我这些年花掉的许多时间,大约都是这样不知不觉散出去的。
有人问我,每天都看书,到底看了些什么。我常常也答不上来。因为我读的东西太杂。有时是物理,有时是数学,有时是计算机,有时又是历史、教育、传记,甚至某个外文名字到底该怎么发音,也能让我查上半天。若按专业产出来看,其中许多东西都没有直接用处。它们不能变成论文,不能变成项目,不能变成职称表格里清楚的一行。可它们一点一点,构成了我和世界相处的方式。
我不喜欢应酬,不喜欢打游戏,不喜欢在热闹场合里消耗时间。别人用来喝酒、闲谈、刷短视频的时光,我常常就这样用掉了。一本书没读完,又打开了另一本;一个概念没完全理清,又去查了另一个工具;本来要学习知识图谱,最后却写了一段 Elisp。看上去东一榔头西一棒槌,自己也常觉得有些荒唐。可是荒唐之中,又有一种安静的自由。
这自由,不是想做什么便做什么的任性,而是仍然愿意被好奇心牵着走。
年轻时,人常常被要求有目标。读书要有用,学习要有回报,时间要能兑换成看得见的东西。这样的要求当然不能说错。一个人要生活,要工作,要承担责任,不能永远只凭兴致。可是若一个人的全部学习都只剩下有用,也未免可惜。太有用的东西,常常离功利太近;功利太近,心就容易紧。心一紧,许多真正细微的乐趣,便进不来了。
我喜欢那些暂时看不出用处的知识。
它们像路边的小草,不值钱,也不被谁认真统计。可你多看两眼,就会发现叶片有自己的纹理,露水有自己的光。Knuth 发明 TeX,原本只是嫌自己的书排得不好看;Stallman 写 GNU,起初也不只是为了商业利益;许多黑客在深夜里写一个小工具,也未必想过它要改变世界。他们只是觉得,这样做更好,更漂亮,更合自己的心意。世界后来得到什么,是后来的事。最初那一点火,常常来自“不为什么”。
我大概也是这样一个老派的人。
前两天有朋友发来一句话,说:“所谓魅力,就是比当下的时代老派一点点。” 她说第一时间想到了我。我回她:那我大概魅力无穷,因为我不是老派一点点,我是老派了好多代。
现在的时代喜欢快,喜欢立刻反馈,喜欢清楚的收益曲线。我却仍然喜欢慢慢查,慢慢试,慢慢把一个小问题弄清楚。别人觉得过时,我倒觉得亲切。
若再往远处说,也许这种学习方式真有点像苏格拉底时代。
我不知道,所以我要问。问了一个问题,又牵出另一个问题。知识不是被整齐地装进脑子里的,而是在一次次追问里慢慢显出轮廓。一个人若能承认自己不知道,便还有可能继续走。最怕的是早早以为自己已经明白,于是好奇心先死掉,剩下的只是熟练和重复。
我当然知道,分岔太多,也会误事。
主路不能总被荒草遮住。该完成的工作,还是要完成;该写的论文,还是要写;该读的材料,也不能因为一个小工具就全部搁下。人不能把散漫说成自由,也不能把拖延粉饰成探索。这里面需要分寸。只是,我也愿意给自己保留一点不那么功利的余地。若每一次学习都必须事先说明用途,必须估算回报,必须直奔结果,那学习便太像一份报销单了。
而我更愿意把它当作一场散步。
有主路,也有岔路;有必须抵达的地方,也有偶尔停下来的树影。走得慢一点,不一定全是坏事。许多真正让人安静下来的东西,都是在慢里遇见的。一个自动计数的小函数,当然算不得什么大成果。可是它提醒我:我心里那个愿意折腾、愿意追问、愿意为一点小小便利花掉半天时间的人,还没有完全走丢。
这就已经很好。
夜里再打开那篇读后感文档,标题一层层折叠着,像一排安静的小门。我按下那几个熟悉的键,一个数字跳出来。它不大,也不响,只在光标旁边停住。可是我看着它,像看见一条分岔小路尽头,忽然亮了一点微光。
我什么都不知道。
但我仍然什么都想知道。