尽管我早在小学的时候就电脑玩得如鱼得水,似乎注定要进入 IT 行业,但后来却经历了屡次失败。今年,当我步入四十不惑时,我终于学会了编程。也许我的经历会让你明白:只要你想开始,就永远不会晚。有时候,你只需要找到适合自己的语言。

“不想成为 Logo 明星程序员后再被派去参加比赛”

我的编程生涯始于 20 世纪 80 年代时拥有的第一台电脑。那是一台叫做 ADAM 计算机的怪兽,就是下图这样的:

这是一种个人电脑、ColecoVision 游戏系统和打字机的混合体:两个磁带机代替了磁盘驱动器 / 磁带盒、一台电视机代替了显示器,还有一台有趣的打印机,上面有个开关可以将它变成一台完整的打字机。很多其他 ADAM 计算机用户都有实际的磁盘驱动器,但这个没有,磁带要花很长时间才能加载出来。

我们刚得到它的时候,我父亲在地下室里录了很多磁带,但我不知道为什么会有这么多的游戏。我最喜欢的一款游戏叫做《Gateway to Apshai》(一款战斗电子游戏),这是一种类 Rogue 的游戏(迷宫探索式电子游戏)。后来他解释说,他是用 Forth 实现的。下面是他的原话:

当我们有了 Coleco Adam 计算机时,它有一个 Zilog Z80 CPU,因此,我用过一点 Forth。不知道你是否还记得,我从美国订购了一盘磁带(用于磁带机的),里面有几个黑客程序和一本名为《Adam 黑客指南》(The Hackers Guide to the Adam)的书,它允许我们将 ColecoVision 的游戏下载到空白磁带上,这样我们就得到了大量的游戏。我自己并没写过任何程序,但是磁带上的程序都附有源代码,所以你可以按照逻辑来写。在某些情况下,我需要调整参数并重新保存,以便优化任何需要破解的程序。这很有趣,也很好玩。

关键是他给我看了一种叫做 BASIC 的语言,当时的我以为 BASIC 是世界上唯一的编程语言。我开始学习这门编程语言,并跟着读了像《银山之谜》(Mystery of Silver Mountain)和《捕获狮头象》(Hunt the Wumpus)这样的书,很快就学会了如何编程。我开始根据 Steve Jackson 的《巫术!》(Sorcery!)这本书制作我自己的小型 RPG 游戏。

它们最后就像下面这段从 Wikipedia 上抄来的代码的一个较大版本,其中有很多RAND的掷骰子和GOTO调用。随着时间的推移,我不得不添加越来越细的行号(比如,在 60 行和 70 行之间添加了一个 65 行,然后是 64 行,最后当我用完空间就得给整段代码重新编号)。

10 INPUT "What is your name: "; U$
30 INPUT "How many stars do you want: "; N
40 S$ = ""
50 FOR I = 1 TO N
60 S$ = S$ + "*"
70 NEXT I
80 PRINT S$
90 INPUT "Do you want more stars? "; A$
100 IF LEN(A$) = 0 THEN GOTO 90
110 A$ = LEFT$(A$, 1)
120 IF A$ = "Y" OR A$ = "y" THEN GOTO 30
130 PRINT "Goodbye "; U$
140 END

所有这些代码都是我自己完成的。那时候,人们还不能在网上搜索示例代码,所以大家都认为我注定要从事 IT 行业。
与此同时,我们在学校里学了一种叫做 Logo 的东西。这就没那么有趣了,你需要做的只是让一只海龟在屏幕上画出形状就行了。你可以给它函数,比如FD 90RT 90,然后用REPEAT 4,它就会重复四次,画出一个正方形。画一个圆要花很长的时间,因为你必须给出REPEAT 360,看着海龟重复 360 次才能画出一个圆。所以有时候你可以作弊一下,执行REPEAR 180,让海龟一次向右 2 度,这样计算机最终会绘制出几乎相同的东西,但只需进行 180 次计算即可。

为了增加趣味性,你可以像下面这样做一个形状,告诉它做一个圆,然后告诉它向右转一点,然后开始下一个圆。

在看到 Bryan Cantrill 的这段视频之前,我几乎完全忘记了我用过 Logo 这件事。Cantrill 年纪跟我差不多,小时候也学过 Logo。我们经历也很相似:对让海龟画圆这件事完全心不在焉,但他幸运地遇到了 C 语言并真正投入到编程中,而我没有。这是我自身的原因。

在 20 世纪 80 年代的计算机课上,我们都坐在 Calgary Ranchlands 社区学校的一间没有窗户的房间里,对着电脑让海龟画圆。由于 Logo 超级容易上手,以至于我和其他几个人都觉得,它根本就不像是一门编程语言。老师们注意到了这一点,就说马上要举行 Logo 竞赛了,我们应该去参加。那应该是一场全市范围的比赛,也有可能是一次省级范围的比赛。

比赛持续了两三天,我们终于在最后一天鼓捣出了一个产品,得到了评委们的认可并有望获奖。我的队友比我更投入,而我却开始表现出对比赛的兴趣缺乏。我觉得我们拿到第四或第五名就可以了,但队友并不满意。所以当比赛结束时,我如释重负。我知道我不想编程,不想赢了比赛后作为 Logo 明星程序员再被派去参加其他比赛。

我当时的人生目标就是让那个我小学时一直暗恋的女孩喜欢上我。还有就是在当时,人们认为会电脑的人都是书呆子。所以那时候,我在公共场合都会和电脑保持一定的距离,来保持这样的形象:是的,我是很擅长电脑,但我并不是一个电脑爱好者或其他什么。

在看了两三天的 Logo-Proficient 比赛和他们所做的东西后,我们得到了一件 T 恤和一个瓶子作为参与奖励,这是我最后一次使用 Logo 。与此同时,我又持续用了一段时间的 BASIC ,直到 90 年代初,我们把 ADAM 计算机换成了 386 ,BASIC 就被我忘得一干二净,而我也不打算花钱买一本关于编程的书。

Bryan Cantrill 第一次接触 Logo 的经历是这样的:

我想我用过的第一种语言是 Logo,现在回忆起来,这是一种虐童的行为,Logo 太可怕了!如果现在你去看 Wikipedia 上的 Logo 词条,你会说:“嗯,这很好,就像一种受到影响的 Lisp 方言……”但是这些都是错的。“Logo 是一只什么都不会做的海龟,我说的海龟就是指大脑袋显示器上的一个三角形,它什么都不会做。它的魔力就像你告诉它“box”(绘制正方形),它会告诉你“I don’t know how to box”。

我记得三年级的时候,计算机是必修课。我还记得当时那种机械、冷漠的感觉,因为这个东西不知道如何绘制正方形,而我也不在乎你知不知道怎么绘制正方形。我第一次接触计算机就是“我对这件事一点儿也不关心”。

Python、Ruby 还是 Lua?

从 90 年代到 2000 年代这段时间,我没有做过任何编程。然而,在这段时间里发生了两件至关重要的事:我成了《星际迷航:下一代》(Star Trek: The Next Generation)和《创世纪 VII》(Ultima 7)的超级粉丝。

Data 是我最喜欢的角色,因此我经常思考 Soong 博士是如何做出来 Data 的,我们需要多长时间才能达到这样的阶段。当我玩《创世纪 VII》时,我曾有过并且现在仍然有同样的感受:这个世界充满了细节,我会继续玩这个游戏甚至只是为了和人们聊聊天、逛酒吧、看人们读书。

所以,这段时间是让我对编程再次感兴趣的重要时期。编程不再是关于海龟和令人沮丧的比赛,而是科幻小说、电影、奇幻游戏、音乐以及其他一切我认为很酷、很有价值的一切。

那时候,我知道有一种叫做 C++ 的编程语言是用来开发游戏的,也许有一天我可以用它做出一个长得像 Android 机器人那样的 Data 和《创世纪 VII》那样的游戏。这让我对 C++ 产生了一定的崇拜,但我已经和编程无缘了。

我从加拿大搬到了日本,然后移居韩国。有一天,我遇到了一位来自多伦多的韩裔加拿大人,他在韩国当程序员。作为一名韩裔,他可以在没有严格的雇主允许让他保持签证的情况下从事自由职业,只需整天坐在星巴克用两种语言进行编程:PHP 和 Python。我知道 PHP 这个名字,一直以为它只是一个电子公告板的名字。他跟我说应该试一试,因为可以很快学到新技能,也会对我的职业生涯有帮助。

他向我推荐了 Python,说应该先从这门语言开始。初次使用 Python 非常迷茫,只有一些小小的成功。我记得我读过关于 Python 2 和 Python 3 的帖子,这些帖子都是说 Python 2 如何更好,Python 3 如何强迫每个人接受的。不管这意味着什么,我注意到一些熟悉的东西,比如print,但熟悉的$却不见了,也没有任何行号或GOTO。在没有主函数的情况下,我设法将一些东西放在一起,但我真的不知道,一个程序没有行号和其他类似有用的东西该如何从头到尾运行。

那时候的互联网开始普及,人们在网上会对一种语言与另一种语言进行比较和讨论。我注意到一种叫做 Ruby 的语言更像我的风格,所以我尝试了一下。然后我又看到一种叫做 Lua 的语言,感觉它好像就是为我做的。我不知道如何使用,但我就相信 Lua 是我想要的。我认为 Lua 是最容易学习的编程语言,如果我能学好这门语言,就能学会所有其他编程语言。

几个月后,我在星巴克又遇到了那个韩裔加拿大人,他问我 Python 学得怎么样了。我告诉他,我觉得 Lua 应该是适合我的编程语言,但我说不出理由,显然我还没有掌握如何写代码。他最后评论说:“嗯,也许你没有编程基因。”

不知为何,我却固执己见地认为自己有这方面的基因。我小学的时候就自学了 BASIC,我知道我有这个天赋。我只是需要真正喜欢上 Lua 并学好它……或者我应该学习 JavaScript?但大家都说你应该先学 Python,虽然我确实更喜欢 Ruby……结果我一直没完没了地纠结着,直到我再一次失去了兴趣。

最后,我又回到加拿大生活了几年,编程根本不在我的考虑范围内。2011 年到 2015 年期间,唯一与编程有关的事情只有一次,就是听说隔壁办公楼里都是写 C++ 的人,他们为管道和其他能源项目定制 SAP,赚钱很多。

40 岁,第一次学会编程

2015 年,油价崩盘,Calagary 经济也随之崩盘,我们整个团队也解散了。拿到了丰厚的裁员补偿后,我决定开始真正学习编写代码。

我学会了如何编写函数,如何创建对象等等,但是self关键字仍然让人困惑,使用对象也是如此。再努力点就足以解决这些问题了,但我的老毛病又犯了:

  • “Python 在制作游戏方面很糟糕——它不会让你做出任何像《创世纪 VII》这样的东西。

  • “为什么不去试试 C++?不,那太难了!C# 怎么样?让我们试试吧。”

  • “哇,这真是太复杂了。尽管如此,C# 看起来是个不错的选择!等等,这是什么?F#?这门语言真的很酷。为什么所有的语言都不是这样的呢?”

  • “F# 太棒了!为什么就没有更多的人使用它呢?也许我应该好好学完 Python……”

  • “那就 Python 吧,又简单又好用!除非是 JavaScript。这样我就可以在浏览器上做任何事情了。也许我可以从一些基于浏览器的游戏开始?是时候试一试了……”

后来,裁员补偿的钱快用光了,必须重新找工作了。找到工作后,我去市区和以前的同事们聚餐。那时遇到了我的一个 90 年代中期后就没见过的老朋友,他在财务部门工作,问我在做什么工作,我告诉他我找到了一份新工作,下周开始上班。“哦,我敢打赌是编程工作对不对!你一直都很擅长编程。”他说。我回答说:“哦,不是编程……我已经很久没有真正做过这些事了。是做项目控制方面的。”

我对这次谈话记忆犹新,因为这让我思考为什么我从来没有学过编程,而且无论从哪个角度来看,我年轻的时候似乎就注定要学编程。不过我当时忙于其他事情,没有再去尝试编程。

我在 2018 年回到韩国。第二年八月,我给当时工作的公司提出了辞呈,那时候我是一名文案。离正式辞职还有一个月的时间,我开始考虑学门技术,也许这次真的要好好学习 Python 了。我可以每天花上几个小时,到最后一天就会掌握得很好,然后再花上一个月左右的时间去找工作。这样做了几天后,我的老毛病又犯了。“好吧,你可以稍微看一下其他语言,”我自言自语地说,“但你必须把 Python 作为重点。”

那是我第一次尝试 Rust 。我听说它确实很精确和高效,但很难学,喜欢它的人会赞不绝口。我是在《 X 分钟速成 Y 》(Learn X in Y Minutes)(译者注: GitHub 上的一个项目,包括了很多的简短的入门教程,比如算法、编程语言、开发工具等)和《 Rust 语言游乐场》(the Rust playground)开始学习 Rust 的。

我开始学习 Rust 的时候,查了一下这门语言的用途,答案无一例外是,它几乎什么都能做。所以我可以做出《创世纪 VII》这样的东西,或者任何我想要的东西。更有趣的是,语言的细节和语言的底层东西并没有让我感到厌烦:我发现自己被吸引得更多了。随着我对这门语言的深入了解,我有了很多怀旧之情。

我写的所有东西都被直接转换成二进制文件,我又可以看到计算机的内部结构了。大量的 Rust 讨论都是关于如何优化代码的,我觉得这很有吸引力。但这门语言很高级也很安全,如果我全身心地投入,它几乎可以使任何事情成为可能(至少在一种语言可以做到这一点的范围内)——这就是为什么我的老毛病完全消失了。

谁知道这种代码会获得成功呢!

 Rust 编程》(Programming Rust)这本书对我来说,刚开始读的时候太难了(一方面对 C++ 和 C 的内容引用太多了),所以我是看了其他书后才回到这本书上,并最后喜欢上了它。

不过,对我帮助最大的是流媒体视频。第一个是 Javascript 开发者 Brooks Builds 制作的 70 多个视频,他把自己看 Rust Book 的每一步都录了下来。看着别人努力学习一门你也在学习的语言,会让你有种在精神上参与的感觉,这是其他类型的流媒体做不到的。“是 mit einer deutschen Familie,不是 mit einem deutsche Familie!”或者“只要用 into_iter()就可以编译了!”等等这些时刻,你会觉得自己真的是在和别人一起学习(事实上你确实是在学习)。

从那以后我开始看 Brian Myers ,他基本也是靠必应(bing.com)搜索学习 Rust 。 Jon Gjengset 我留到了最后看的(这是在 《Crust of Rust》教更简单的东西之前),同时也看了 Hello Rust  Ryan Levick  Doug Milford  Tensor Programming  this Rust crash course  dcode 的 Rust 视频等所有的视频(不是全部按顺序排列的)。还有一个我喜欢的视频流就是 rhymu8354 ,他是一个 25 岁的 C++ 爱好者,自己做了一个类似《创世纪 V》的游戏,最近开始学 Rust。

半年后,我发现我有生以来第一次正确地学会了编程。然而并没有什么秘诀:真的是单一的专注和勤用必应搜索的结果。

由于只有一个 Surface Go 笔记本,我一定要避开任何有太多外挂的东西。但我做了一些东西,比如朝鲜汉字转换器(朝鲜汉字就是韩国使用的汉字),效果很好,最后我还整理了一本名为《用简单的英语学习 Rust 》( Learn Rust with easy English)的教材,目的是为了让那些英语二级水平的使用者更容易学习这门语言,而不必用翻译成他们国家语言的 Rust 相关书籍。

这个故事的寓意我想就是经典的“找到自己喜欢的事情,然后一直做下去”。这对我来说并不新鲜,只是我花了那么长时间才找到适合自己的语言。它让其他语言变得如此易读易懂,包括 C 和 C++。

我想说明两点:一、见异思迁和缺乏专注不一定是永远的;二、每个人性格不同,最简单的语言不一定是你最喜欢的语言。

Reddit 网站上的 /R/LanguageLearning 等版块上经常有这样的讨论:“我真的很想学(著名的 X 语言),但我是否应该继续学更简单的西班牙语 / 法语等,尽管我讨厌它?”答案当然是否定的——只需学习你想学的语言就行了。这种建议更容易给出,因为自然语言并不像编程语言那样与职业发展紧密相连。但是由于编程语言也有很多后继的东西,同样的建议也许是可以适用的。

Rust 肯定不是那种为了成为大团队中的初级程序员而学习的语言,更不用是在 40 岁年纪的时候。但是,如果你是那种对编程屡次三番捡起后放下的人,也许找到合适的编程语言会让你坚持下去。

作者介绍:

Dave MacLeod,加拿大人,居住韩国首尔。职业翻译,精通韩文、日文、德文、法文、英文。业余 Rust 开发人员。

原文链接:

https://github.com/Dhghomon/programming_at_40/blob/master/README.md