CodeLab 纪事

大多数想法来自过去的旧想法。 -- Alan Kay 《The Early History Of Smalltalk》

记录我所经历的 CodeLab。

CodeLab 实际发生的故事,有无数细节、有许多人的共同努力。我只看到其中的一部分,由于记忆的不牢靠,造成的遗漏肯定很多。

如果这些记忆有什么差错,恳请大家指出。

怎么开始的?

问这问题的人,在期待一个跌宕起伏的故事。

这故事的开头,要是从辍学开始就更好了。

如果此刻坐在街边大排档,盛夏晚风带来油烟和凉意,干一口冰镇的可乐,也许我能把这故事说得更有味儿些。

但此刻没有晚风和可乐,CodeLab 也不是这样开始的。

生活通常平淡无奇。

当它显得非凡,可能是因为遇到非凡之人。

园丁

桃李春风一杯酒

对 CodeLab 来说,几位理事就像园丁。

与大家结识,最初因为一个开源项目: Open edX, 这个项目试图变革高等教育,使其线上化,推动教育公平。我在个人博客里为 Open edX 写过不少文章,大家因为这些文章结识于网络。

开源开发者是志愿者,因为兴趣和能力是自主选择的 --《大教堂与集市》

几位理事中,最早遇到 @zeng。 2015.4.23 @zeng 给我发邮件说:

我是 www.edustack.org 的成员 。我们目前在做一些关于Open edX的项目工作,不知道你是否有兴趣以网络的方式参与?

与 @zeng 围绕 Open edX 进行了长期的网络协作, 一起组织过几次的线下 Meetup、一起去到采用 Open edX 的高校做技术分享、一起参加了 UCSD 的Open edX全球大会... 与 @zeng 碰巧是福建老乡,由于兴趣和观念的投缘(喜爱的书单重叠度也高),从最初的项目合作,发展成志趣相投的好友。

教育不是注满一桶水,而是点燃一把火 -- W. B. Yeats

@zeng 在高校任教, 热爱开源(Open Source)文化,开设与开源相关的选修课, 为构建氛围良好的学生社团(计算机俱乐部)而投入大量精力,致力于让在校的学生尽早接触开源文化,融入线上开源社区。

关于 CodeLab 的早期想法,来自与 @zeng 的长期交流。 虽是好友,但我一般叫他 @zeng 老师。 关于开源、社区、教育相关话题的观点,大多是与 @zeng 老师的多年交流而产生。 他是我遇到最好的教育者之一,一个像苏格拉底一样喜欢跟你聊天辩论而“不会教你很多编程技巧”的人。

CodeLab 的名字是 @zeng 起的,在一次 Meetup 路上。

同行者稀。 智识与良知上的同行者尤难遇见,这是友谊之可贵而难求的一个原因。


一个人决定放弃地图而选择指南针,是因为他认识到在日新月异的世界中,一份详细的地图可能会将你引入密林深处,带来不必要的高成本;而好用的指南针却总能带你去你想去的地方。 --《爆裂》

来广州之前,我在南京,@CC 也在。 喜欢南京这个城市,尤其是灵谷寺的萤火 燕子矶的落日、童家巷的梅花糕和二楼南书房。

2017年在南京折腾一个创业项目,因观念分歧而退出,恰逢分手,心情苦闷。出门漫无目的徒步旅行了一个多月,在泸沽湖停留了两周,期间读完朋友 @M(因创业项目结识)推荐的《爆裂》,对 MIT Media Lab 及其所做的 Scratch 很感兴趣。之后梳理了Scratch的前世今生, 相比于后来 Lounsen 的《编程教育60年》三部曲,显得非常逊色,但当时这方面的计算机考古还不多。 了解到这个领域的先驱们所做的探索后,被深深打动。想在这个方向继续做点东西,几乎是一种使命感。

旅行结束回到南京,除了晒黑许多,也不像出发时那么苦闷,或许是因为有了新目标。那段时间,每周和 @CC 碰一次面,一般是中午约在湖南路的凤凰书城,聊《爆裂》这本书的观点,聊 Scratch 的惊人社区,也聊未来的一些规划,持续几个月的讨论,思路逐渐清晰, @CC 想为这些想法拉来投资,我则倾向于以开源社区的方式来做。

当时的基本想法是进一步增强 Scratch 的能力。 为了进一步增强它的能力,我想为它设计一个可生长的插件系统(这个想法后来让我跌入 Alan Kay 的兔子洞里), 当时将这些想法梳理成了2篇文章:

一边写架构设计相关的文章,一边着手实现软件原型:Scratch Adapter。 这个项目后来演变为 CodeLab Adapter,致力于将物理世界和异构的软件系统,通通接入Scratch。


教育指导社会,而非随逐社会也 -- 蔡元培

那段时间兼职为英荔教育公司提供 Open edX 架构咨询服务。大约2018年4月份,英荔教育(当时在做在线商学院)的技术总监 @红黑军团 邀请我到广州做一次技术分享,他们想把自己围绕 Open edX 的技术工作开源出来,共享给大家, 后来英荔教育成为国内在个领域开放了最多源代码的企业,在 UCSD 举办的 Open edX 全球大会上,英荔教育的董事 @Wei Yang 做了一次演讲。

这次分享会围绕开源文化与社区展开讨论,分享会上结识了 CodeLab 重要的几位早期志愿者: @Finn(与Finn在2020年初一同拜访过MIT Media Lab、Dynamicland、The Clubhouse Network)、@Leeyi(Leeyi是英荔教育副总,为CodeLab提供了无尽的帮助)。

分享会上,也结识了后来成为 CodeLab 理事和资助者的 @Jackson。

当时 Scratch Adapter 原型已经可用,可以连接一些小玩意儿,拍了几个好玩的小视频,由于聊到开源,我便分享了最近在做的这个东西,说正打算开源出来,忙于写文档。大家觉得这玩意儿挺好玩, @Jackson(当时还不认识他)问是否考虑接受投资,我说不考虑,想做成开源社区。@Jackson 说他有兴趣参与,如果我之后想清楚怎么做,可以跟他聊聊。晚饭后, @红黑军团 、 @Leeyi 和 Finn 送我回酒店路上,向我介绍了 @Jackson 的经历和目前在做的一些事情(包括投资)。

由于 MIT Scratch(社区)以非营利组织运作,我也想在国内做一个类似的开放社区。 据说新手的第一部小说通常会模仿自己最喜欢的那部小说的风格,看来不独是小说写作如此。

我把想法跟 @Jackson 分享之后,@Jackson 说他想参与,可惜不懂计算机技术,在技术上帮不上忙,但乐意提供其他方面的帮助。 @Jackson建议我们全职来做这件事,这样会比松散地推进它来得有成效。如果全职来做的话,他愿意无偿资助这个非营利项目。

我倾向于先达成一些观念上的共识,避免之后发生重大分歧。由于准备追随《终身幼儿园》的理念,便把这本书推荐给 @Jackson,说如果你也认同书中的理念,我们就可以一起规划这件事,如果不认同可能并不契合。

@Jackson 用一周时间看完《终身幼儿园》,说他十分认同书中的观念,他还把这本书买来送给周围可能需要的朋友。

CodeLab 的故事就此开场。

故事发生地: Neverland

后来,他领着我飞到了永无乡,那儿还有仙子,还有海盗,还有印第安人,还有人鱼的礁湖;还有地下的家,还有那间小屋子。 --《小飞侠彼得·潘》

由于 @Jackson 的慷慨资助(方方面面,甚至在装修上也付出了巨大力气),CodeLab 顺利在广州注册为非营利组织,并租下了办公室。我们花了不少精力装修新的办公室: Neverland, 一个可编程的空间

Scratch 构建了精彩的虚拟世界,大家都喜欢在 Scratch 的 舞台区 表达新想法。当我们受 Dynamicland 的影响,将编程环境的概念延伸至现实世界时,我们便开始了可编程空间之旅: Neverland。

我们在其中办公,在其中编程,在其中玩乐,在其中做一些有趣的探索和创作。

Neverland 设计方案是 CodeLab 的早期参与者一同头脑风暴出来的, CodeLab近况里记录了当时讨论的许多细节。

同伴

Projects, Passion, Peers, Play --《终生幼儿园》

远程协作

寻找同伴是困难的,尤其是寻找一群理念相同的同伴。

招募到全职小伙伴之前,CodeLab在技术方面的工作(最重要的一项是构建在线社区),完全由早期的志愿者通过在线协作的方式推进。

@summerscar(前端) 和 @hidaris(后端) 为此付出了最多的努力。

我们当时的目标是构建出完全与 MIT Scratch 兼容的社区,可 MIT Scratch社区后端并未开源,我当时写了Scratch3.0技术分析系列的十篇文章,希望通过分析后端API,来实现出与之兼容的设计。 这一系列的文章希望实现以下目标:

  • 理解 Scratch 的架构设计
  • 理解 Scratch 拥有强大兼容性的原因
  • 梳理 Scratch 背后使用的一些设计理念(Smalltalk)
  • 按照 Scratch 一贯的设计原则,独立实现 Scratch 并未开源的部分。确保之后能随着 Scratch 一同升级,架构上保证向后兼容。
  • 顺着 Scratch 的思路,对 Scratch 作出改进。

总而言之,我们希望通过这些分析,获得定制 Scratch 的能力,但同时又能与上游的官方版本保持兼容。我们重视官方对 Scratch 的持续改进。与其说我们重视他们技术能力,不如说我们重视他们对教育和社区的深刻理解,这些是极为稀缺的,它不是技术问题,也不是资金问题。我们希望能随时将官方的改进 merge 回我们调整后的项目中。我们不希望做出硬分叉。 --Scratch3.0技术分析之后端API(第0篇)


全职小伙伴

最早加入的是 snownstone , snownstone 在2019年4月19日给我发了一封邮件, 我从邮件里得知读库拿下了《Mindstorms》的版权,这本书出版了40年之后,首次有了中文版。 因为 Mitchel Resnick 和 Bret Victor 的影响,我当时正在看原版《Mindstorms》。

今天下午,我在google里搜索Alan Kay 与Pharo时,链接到了你的个人网站,其中围绕少儿编程、Alan Kay的内容令我兴奋不已。 (我发现我很难用语言准确描述自己的情感,下面我就干脆过滤掉情感平铺直叙了。)

前段时间Seymour的Mindstorms这本书,我完整阅读了两遍,最终写了一篇文章放在了公司的公众号上。在书前的序中,Alan Kay的名字被提到,由此我又发现了一位让我惊叹不已的人。最近这些天,我就一直在看Alan Kay曾经写的文章,Youtube上的演讲视频,搜索他相关或提及的关键词,也由此发现了你们。

我的背景是心理学,硕士毕业于中科院心理所,之前用过matlab,但是真正的编程经验约等于零。因为一直想独立做一个网站,且对视觉刺激有特别的感觉,所以前段时间开始在codecademy上学习h5和CSS。Jeffrey Zeldman创办了网站A List Apart 以及出版社 A Book Apart,主要是围绕Web 开发的内容,前段时间也兴奋地看了一些,这也是我阅读Mindstorms的背景,Alan Kay强调的context。

我上周向公司提了离职,接下来暂时不打算找工作,想要认真专注地学一些东西,做一些自己的事情。写这封邮件也是想或许可以和你们一起做些事。

不知道你们是否知道,读库出版社去年出版了Mindstorms这本书,中文译名是《因计算机而强大:计算机如何改变我们的思考与学习》。如果你们尚不清楚,这本书的统筹编辑杨芳州老师(也是读库副主编)在个人公众号(寻找局外人)中写了一篇文章,《为什么要出一本四十年前的书》,可以了解一下。读库是我非常喜欢的一家出版社,基于Seymour的这本书,我想CodeLab可以尝试和读库一起做一些线下活动。此外一土教育应该也值得考虑。

我看到你们正在规划CodeLab Mindstorms项目,计划做的事情也是我最近在阅读过程中有想过的,或许可以加入一起做。我平时的英语阅读量还是挺大的,虽然翻译工作确实没做过,但还是想尝试做。此外,这个部分我其实也在想CodeLab或许可以与读库合作。作为一家出版社,他们有优质的翻译、插画、编辑资源,还有发表渠道,如图书出版、《读库》mook出版。

你们非常看重的Mitchel和Scratch,我现在还了解不多。在纪念Seymour的一些视频中看到了Mitchel,知道他的 4P 理念。但当下我个人最感兴趣的是Seymour、Alan他们关于学习、思考、理念、计算、人机交互等基础性的思想,我在其中感受到秩序与方向,这是我现在首先需要满足的个人需求。接下来我会去试试看Scratch、Smalltalk这些编程语言。

snownstone 的邮件非常打动我,无论是她的心理学背景、信里谈论的东西还是文辞风格。于是我去北京和 snownstone 见了个面, 约在万圣书园,那儿有很多不错的哲学书籍。聊得很开心,回到广州之后,我邀请她来广州参观 Neverland,在 Neverland 再次沟通之后,她便决定全职加入 CodeLab。

snownstone 在加入之前,阅读了 个人计算 领域大量的资料,对于 Seymour/Logo 以及 70年代发生在施乐实验室前后的事情,都有深入了解;加入 CodeLab 之后,snownstone 借着 Scratch 重新踏上编程之旅, 在音乐和声光电方面做了很多探索:

目前所有工作都源自最开始想要通过声音和视觉(包括平面和灯光)为空间渲染气氛这一简单想法,使用 Python、CodeLab Adapter 和 Scratch 做一些交互。

物理世界中音源的振动只有引发空气的振动并传至外耳道引起鼓膜振动,才会被我们感知即听到。所以整个过程的前半段属于物理范畴,关于振动与波;后半段则属于生理心理范畴,关于我们对振动的感知,声音的响度就是一个心理概念,大致对应物理概念振幅。 -- 使用 Python、Adapter EIM 与 Scratch 绘制流动的音乐频谱

如果你对 snownstone 的工作感兴趣,可以留意她近期梳理的东西。

snownstone 对色彩、美学和科普有着广泛兴趣,与之相关的,她设计了 CodeLab 当前的主站(与 @summerscar 协作),写了几篇精彩易懂的可科普文章:

可编程舞台、Neverland2.0(魔法主题空间)的构想也来自 snownstone, 这些想法都曾一度让所有成员激动:

可编程舞台

可编程舞台 ppt

Neverland Mindstorms

从最早 snownstone 邮件中提到的:

但是真正的编程经验约等于零

到现在与计算机建立起亲密关系,时间并不长,如果去看 snownstone 最近做的东西(NeverlandBeats),难以相信,这是一个 Python 新手的工作。

trackthebeat1

trackthebeat1

trackthebeat2

我很怀疑自己在使用Python 3-5年之后,能力是否可以与 snownstone 相提并论,snownstone 正儿八经写 Python 是的时间甚至不到一年。这是对《大教堂与集市》以下观点的一个注脚:

乐趣预示着效率。

snownstone 可能是一个很好的例子: 将计算机看作一种表达媒介(个人计算提倡的视角),使用它探索和表达自己的兴趣(对她来说可能是音乐、色彩、情感表达...)能走得多远...


传递编程的乐趣, 鼓励孩子成为数字时代的创作者 -- CodeLab 使命

@麦可 可能是我们之中,这个使命最为执着的追随者。 也可能是 CodeLab 里,对编程教育最有热情的一位。

@麦可 加入时的最初兴趣是教研,加入CodeLab之后,开始对 个人计算(受Scratch/Alan Kay影响) 和 公共空间(受Bret Victor/Dynamicland影响)抱有极大热情。

最初的邮件里,@麦可 提到:

我毕业后从事的工作其实也和编程教育有关,最开始加入了一家做教育机器人的公司,现在则是在一家做少儿编程教育的公司做课程设计。在这个过程中,也有机会了解到目前教育的现状,在升学压力下,教育常常偏离方向,虽然 STEM 教育理念很好,但在推广过程中常常要给应试教育让步,小朋友的课余时间和周末经常被各种培训班塞满。教育改革不是一件容易的事情,所幸技术平民化加速了教育改革的脚步,现在的小朋友更容易接触到开源的教育工具,如 Scratch、micro:bit,有了这些易获得的工具,他们得以更好地表达自己的想法。

创客空间在国内兴起的时候,我觉得是一个非常有意思的地方。里面提供了各种各样的创造工具,还有一群志同道合的人互相交流。不过,因为设备和场地投入,加上没有很好的盈利模式,创客空间往往难以自负盈亏。能不能做一个低成本的家庭版创客空间呢?只有当工具的成本足够低,让人人都可以获得时,它才能真正发挥最大的作用,Arduino、micro:bit、树莓派都是这样的产品。后来了解到你正在做的 Neverland 项目,它在创客空间的基础上更进一步,将空间本身也变成了一个游乐场。正如你所描述的,用 CodeLab Adapter 连接智能硬件和 Scratch,打造编程的魔法空间,我想小朋友一定会喜欢这样一个地方。

我们谈到教育时常常默认是学校的教育,家庭教育经常被忽视。杜威“教育即生活”的理念阐明了教育蕴含在日常生活中,家庭作为小朋友每天长时间生活的场所,如果能改造得更加适合小朋友探索和玩乐,是一件很有意义的事情。公立教育改革因为涉及的因素太多,往往推动缓慢,而对教育非常重视的家长,如果能认识到家庭教育的价值,加上 Neverland 提供的思维实验室,相信能激发很多可能。

在CodeLab, @麦可 探索了多种编程教育形式,从我们第一次联合壹航教育以及英荔教育举办的公益编程夏令营

到 16 个周末编程工作坊:

再到后来倾注了大量精力制作的两门线上课程:

这些课程背后的观念,大多来自 CodeLab 日常讨论的共识。

围绕:

传递编程的乐趣, 鼓励孩子成为数字时代的创作者

@麦可 付出了巨大努力,CodeLab社区里的CodeLab官方账号 也主要是 @麦可 在维护。

@麦可 的加入除了带着大家更多接触编程学习者,探索编程教育的各种可能性,也为 CodeLab 带来了许多其他影响。我们在协同工作上取得的一些重要成果,很大程度是因为 @麦可 对协同方式的建议带来的。如果不是因为 @麦可, CodeLab 的共识会比现在更弱。


在计算机科学中保持计算中的趣味性是特别重要的事情,这一学科在起步时饱含着趣味性 -- Alan J.Perlis《SICP》序言

@kaikai 是最后一位加入 CodeLab 的同伴。

我发现了您发布的CodeLab招募博文,并被深深的吸引,随即翻看了几篇相关的介绍和官网的博文,就像一开始我被编程吸引一样。因为CodeLab在做的事情,使我回想起我编程的初心,那时没有工作的压力,只有喜欢和简单的快乐。如果不是为了要在生活、收入与兴趣之间做权衡,真的就想这么一直快乐下去,和有意思的人在一起做有趣的工作。

想加入codelab, 因为不知道对计算机的这些广泛兴趣,在其他地方能干嘛。

@kaikai 加入时,刚毕业,计算机科班出身,对计算机有着广泛兴趣。 这兴趣由来已久,自少年起,持续至今。

@kaikai 加入 CodeLab 的最初兴趣是参与构建类似 Dynamicland 的东西,之后卷入 Scratch 和 个人计算的漩涡。@kaikai 意识到 Scratch 舞台区的重要性,它是促使孩子愿意在社区里玩的最重要元素。

Scratch的舞台区有点像古希腊雅典城的广场,有一个大家都可见、可参与的公共区域,人们于是可以轻易地展开交流,分享自己的想法,人们可以在这广场里走来走去,看看别人在讨论些什么,要是感兴趣就参与进去。由于Scratch舞台区是一个视觉区域,拥有强大的媒介属性,“很容易卷入进去”(《理解媒介》)。

为了增强舞台区的力量,@kaikai 在这块投入了巨大的热情,目前最受社区用户喜爱的物理引擎,便是主要是 @kaikai 的工作(基于 griffpatch 的工作,@麦可 也给了许多改进建议)

@kaikai 在 CodeLab 的另一个重要工作是构建了 Scratch 激光雷达相关原型,从雷达的驱动选择、更好的全屏支持到插件的实施。 激光雷达相关的项目深受孩子们的喜爱。这个项目也与舞台区有关, 它将 Scratch 舞台区搬到现实的地面上!

CodeLab社区/kaikai 在社区里分享了很多激光雷达有关的项目。

CodeLab Scratch 最大的一次升级: 高级编辑器,来自 @kaikai 和 @summerscar 的密切协作

实习生

除了全职小伙伴,CodeLab 先后还接纳了几位实习生,他们各自对实习经历已经做了记录(另有一位实习生 @Leon 忙于课业(疫情期间,需要远程完成学业),还未对实习经历做记录):

@Lounsen(《编程教育60年》三部曲的作者,三部曲中的第三部分有介绍CodeLab在做的事情)近期原本计划来 CodeLab 实习,很可惜由于 CodeLab 的变故,未能有共事的机会。 @Lounsen 是这个这个领域最深入的思考者之一, 也是最有远见的从业者之一。

我喜欢亚当斯密在《国富论》中对哲学家的这段赞美:

他们的职业就是什么事都不做,但要观察每一件事情,因此,他们常常能把相距遥远和极不相同的事物的力量连结在一起

当 @Lounsen 把准备交付给读库的《编程教育60年》完整版的初稿分享给我时,再次读完这三部曲,想到亚当斯密的这句话,我回复 @Lounsen 说:

这篇文章正是将相距遥远事物的力量连结在一起, 我想每一位认真对待它的计算机/教育/互联网从业者都能从中获益。


探索与收获

认识你自己 -- 德尔斐箴言

说说我自己(@种瓜)在 CodeLab 这趟旅程中的探索和收获。

将参与 CodeLab 的工作视为人生最可贵的经历之一,在这里,我开始自由思考,追随理念,积攒勇气,避免绝望和沉沦;并学会信任同伴,真诚讨论,寻求共识。如果没有 Jackson 的慷慨资助,则这些事情都无法发生;如果没有身边这些同伴,我又会重新陷入虚无主义。 -- 夜行人/aboutme

看待 Scratch 的视角

point of view is worth 80 IQ points. -- Alan Kay

诱使我踏上 CodeLab 之旅的那只红眼兔子(《爱丽丝梦游仙境》)是 MIT 的 Scratch。

Scratch 是那种第一眼,你会归类为“小孩子的玩意儿”的东西,尤其对于长期浸淫在 Unix 文化里人。 在舞台上控制一只小猫咪?让它走一走叫两声?这东西显得有点幼稚。

在柏拉图的对话集里,苏格拉底的那些对话乍看起来质朴得近乎粗俗,总是一些鞋匠、木匠、铁匠的比喻。等到被他隐藏在对话之下的东西抓住,就极为震惊,怎么会有这么清晰而深刻的东西!

Scratch 是如此深刻,这种深刻隐藏在涂鸦风格的表面之下。投入时间越多,它显得越不可思议,这很奇怪,过去我所投入时间的系统,不久就会抵达“哦原来如此”的境地。Scratch 不是这样,越是深入系统背后的想法,越觉得隐藏着更深层的东西。我曾一度以为是一种过度解读,告诉自己说这东西不值得投入那么多时间。但随着时间的投入, 我对计算机和编程有了全新视角。 后来我知道那是遗留在Scratch中的“个人计算”理念闪烁的光芒。之后 Scratch 成为我进入 Seymour Papert、建构主义、 Alan Kay、Smalltalk、Dynamicland 的入口。

我准备采用三种视角深入这个系统:

  • 源代码视角
  • Smalltalk视角
  • 建构主义视角

再之后,打算批评一种过分看重积木的视角。

源代码视角

源代码视角上, Scratch 由许多部分构成, 和大多数在线编程环境一样,包含前端、后端。

Scratch 的所有前端项目都开源(包括社区),在终生幼儿园小组的Github页面上能找到大多数源代码。 后端项目都没开源,一种可能的猜测是,MIT 不希望社区分裂得到处都是。

当我们谈论 Scratch 编程环境的时候,谈论的是前端部分。

当前领域过分看中积木: scratch-blocks(基于Google Blockly),而轻视了 scratch-vm

scratch-vm 是 Scratch 最核心的一部分。 这 vm, Smalltalk 风味十足,因为初代的 Scratch 基于 Squeak(一种Smalltalk方言)实现,后来的版本只是换了语言,重新实现初代的设计。 从 JavaScript 来看,这 vm 显得很怪异,不像用JavaScript写的东西。 即便阅读 Scratch 源码解析相关的书籍,依可能一头雾水。解读者只是对源码细节做些功能上的注释,背后的设计理念,如果不去理解 Smalltalk,是难以理解的。

@summerscar 对源码的了解比我深入很多。

Smalltalk 视角

Smalltalk 社区的个人计算精神流淌在 Scratch 的方方面面。 它颇似泉眼,会越往下挖, 水流越是奔涌。

@Lounsen 是这个领域最出色的探险者之一,顺着 《编程教育60年》三部曲, 跟随 @Lounsen 的脚步,将看到沿途令人惊异的风景。Scratch 是这趟旅行出发时的目的地,但途中的风景甚至比目的地更为壮阔。

如果你的野心是设计出比 Scratch 更好的图形化编程环境,与其对着 Scratch 模仿,抄其皮相,更好的方式,可能是理解塑造它的思想和理念,事物在早期通常显得质朴,不会像后来淹没在太多无关紧要的细节里。

在此只列出对我影响很大的一些文章:

此外,这几个项目也对我产生了巨大影响:

  • Etoys
  • Squeak
  • Morphic
  • Dynamicland
  • Lively

更多影响我的东西,放在了我的个人博客上。

以 Smalltalk 视角看待 Scratch,两个地方尤其值得注意:

  • 舞台区
  • 消息与角色

舞台区

计算机只是一种乐器,它的音乐就是思想。 -- Alan Kay

舞台区是一个"可见的世界": 一个图形化的世界,用户很容易把自己脑子里不可见的想法在此投射出来,通过操控角色,在舞台区演绎想法,这便是在 Scratch 中编程的体验。

Scratch是表达想法的一种媒介,就像纸、笔、乐器这些东西。 它的特殊在于它是一种动态媒介(Personal Dynamic Media),要比纸、笔、乐器灵活,你可以在舞台区模拟这些东西,它是 Seymour Papert 说的 1000 种形式的齿轮。

齿轮所不能完成的,计算也许可以。计算机就是机器里面的海神普罗透斯,其本质在于它的普遍性,它的模拟能力。因为它可以变成一千种形式, 实现一千种功能,所以它可以满足 1000 种需求。 -- 《Mindstorms》

Scratch 舞台区是 Smalltalk 图形用户界面(GUI)革命的一个产物。 从这里,你能看到 Smalltalk 社区许多关于 图形用户界面 的想法(User Interface: A Personal View)。

scratch-vm 中有大量代码是关于舞台区的,即便是其他代码(诸如积木),也多是为了舞台服务。你可能会反驳说,声音并不属于舞台,但是在典型的用例里,声音是由舞台角色发出的。

消息与角色

制造伟大的、可成长的系统的关键是设计出模块之间的沟通机制,而不是关于内部属性和行为应该是什么。 -- Alan Kay

从Scratch社区野生成长起来的孩子,相比变量,更喜欢使用消息(message),我遇到过把变量设想成消息的一种特例的少年(Hanson)。

(Hanson 在北京读初中,他接受过我们一次访谈:编程少年1+1访谈,Hanson 成长于Scratch社区,拥有惊人的学习能力,使用Scratch/LISP/Python/Smalltalk 探索自己的兴趣,他最近一次跟我讨论的话题是在使用 Python 模拟生物圈)

但来自传统编程社区的用户(大多数教育者)通常喜欢使用变量,因为他们在 C/Java 课堂上学过这东西。

有过面向对象编程经历(诸如Java/C++)的用户,进入 Scratch 的第一天通常非常恼火: 怎么让一个对象直接操控另一个? 他们发现 Scratch 竟然不支持对象之间彼此调用方法,于是得出结论说, 这真是孩子们的幼稚玩意儿。 作为临时策略,他们很可能创建一个全局变量,然后共同操作这个全局变量,来实现对象之间的协同。

真正的 Powerful Idea 是使用消息: 对象通过消息来沟通。

在 Smalltalk 世界观里:

消息:应将计算视为对象的固有功能,可以通过发送消息统一调用它们。 --《Smalltalk背后的设计原则》

显式处理对象存储时程序会变得混乱一样,如果在外部执行处理,系统中的控制也会变得复杂。 --《Smalltalk背后的设计原则》

Alan Kay(面向对象先驱)发明 面向对象 这个词时,所指的并不是C++/Java社区流行的面向对象(面向对象编程(OOP)的两大学派)。Alan Kay指的是在于彼此通过消息沟通的小物体,这些小物体解释自己收到的消息,据此作出行动决策,它们是自治的(Agent)。 你可以把Alan Kay的对象看作对计算机本身的递归(《The Early History Of Smalltalk》),每个小物体都保留了计算机的所有能力,如此一来,决策可以被一直推迟(任何对象都 有能力 对计算作出决策),而不是一开始就得规划好,这种系统是可生长的,支持晚绑定(late binding)。

她尝遍每个异乡限时赠送的糖 --《历历万乡》

如果你来自 Smalltalk 或 Erlang 社区,或许会觉得 Scratch 有一种故乡的亲切感,Scratch正是 Alan Kay 设想的面向对象的产物, Smalltalk/Erlang 也是如此(Erlang作者不认为Erlang受到Smalltalk的影响)。

面向对象应该在第一堂编程课教给孩子,把它当作一种思考事物的方式,一种元能力,而不是把它看作一种数据结构,这不是对错问题,是视角强大与否的问题。

面向对象在编程教育中的重要性, Adele Goldberg 和 Joan Ross 在 Is the Smalltalk-80 System for Children?中做了充分讨论。这是编程教育领域最好的文章之一。

如果给你一些可玩、可扩展的东西,诸如写有段落的纸张,请你重写它,这比什么都不给你,让你在白纸上写东西来得容易。因此,对专业程序员和孩子们而言,这是比较好的一种教育方法,从一个能做一些事情的对象开始,或者把多个对象放在一起,让它们互动,之后扩展它们,让它们的行为有点不同,你可以采取一种渐进的方式来学习如何控制计算机系统。 -- Adele Goldberg

建构主义视角

For fuck's sake, read "Mindstorms". -- bret victor Learnable Programming

Smalltalk 社区个人计算精神只是 Scratch 的源头之一。 另一个源头是 Seymour Papert。

当你在 Scratch 里,对着舞台上的一个对象(角色)编程时,你可以把你在现实世界的经验迁移到被编程的对象里。你设想它饿了要如何行动,设想它遇到危险怎么办,设想它碰到墙壁怎么办,设想它打雷下雨啦要躲到哪里。按照皮亚杰的说法,你在 同化 你的知识和经验。 想象你是这个角色脑袋里的小人(马文.明斯基),你要如何指挥自己的身体?要如何决策? 通过教会舞台去的角色行动,编程者学会思考思考这件事本身。这正是编程的重要意义。Seymour 在《Mindstorms》对此有精彩阐述。

关于建构主义对 Scratch 的更多影响,参考 @Lounsen 的文章。

批评过分看重积木的视角

简单的事情应该是简单的,复杂的事情应该是可能的。 -- Alan Kay

我们以一篇批评来结束对 Scratch 的讨论。

人们通常将 Scratch 看作一种积木化编程环境,当前领域十分看中积木,以为 Scratch 的精髓在于积木,我来解释下这种视角产生的灾难。

过分看中积木,导致了当前领域的大多数项目相比于 Scratch 是一种巨大 倒退。手握倒车档的企业和开发者, 丝毫没有松手的迹象,踩着油门一路加速。

这种观点既然认为积木是关键,便灵机一动, 退回到 Blockly(毕竟 Scratch 也用到了 Blockly),所得到的东西是一种 图形化编译器

大多数基于Blockly的项目,会将用户拖拽的图形化程序 转化 为 Python/MicroPython、Arduino(Processing)、C++、C 之类的代码, Blockly所干的工作,非常像编译器。

编译器(compiler)是一种计算机程序,它会将某种编程语言写成的原始码(原始语言)转换成另一种编程语言(目标语言)

这事乍看起来挺聪明,你看,新用户不是疏于语法吗?不是连打字都不顺畅吗?通过拖拽图形不是可以降低门槛吗?

当然,这些都是对的。

只要你不实际编程,这想法就没啥毛病。 于是那些自己不编程,却有权力来决策的人, 纷纷举手赞成这“聪明”的做法。

可是, 一旦你结束 hello world ,踏入真正的编程世界,就开始面临陡峭、不可理解且不正交的系统。 这对入门用户来说简直是一场灾难。

这最初据说是为了帮助用户入门的图形化编程系统,摇身一变,成为一头在泥塘里打滚、面目狰狞的巨兽,吞噬初学者的理智和耐心。这图形化编译器里,到处都是开发者的小聪明。 自动生成的一团代码,一旦出了问题,基本不可调试(debug), 因为自动生成的代码,大多是不可读的,而调试偏偏又是初学编程最重要的过程, 因为错误总会发生。

迄今为止, 纵观整个领域, 只有微软的 MakeCode 是令人满意的, 微软团队在这块之所以能做得不错, 除了投入巨大的努力,更重要的是他们之前在编译器方面丰富的经验(想想 Visual Studio)。

只要下载这些软件用上一段时间(大多数还相当知名),随处可见让初学者晕头转向的代码,你只是简单想实现按下按钮就亮起led,可能立刻会得到 asyncio 控制的协程。 如果你打算继续做些其他事,就会生成并行任务相关的异步代码,asyncio.gather..., 由于是自动生产的代码,聪明的开发者给各个函数加上下划线, 这些自动生成的函数名,通常毫无意义(只服务于功能需求),这肯定是非常糟糕的命名风格 , 站在工程的角度,这做法聪明精巧。 但是这些不可读甚至有误导性的代码你真的准备让一个初学者去看吗?

程序是写给人看的,只是碰巧能在机器上运行。

此外,我还要反驳这种辩解: "用户不应关注代码,去关注实现的功能", 这辩解很精妙,它甚至可以扯上建构主义: 在理解之前动手去做,所以生产的代码虽然可读性很差,但它能运行呀!

我不接受这种辩解,首先它不一定总能运行,虽然官方的例子通常能运行,但用户的新想法很可能处处碰壁(因为设计一个好的编译器非常不易,大多数团队根本不具备这个能力,这些积木很可能不正交)。 论点之二是,如果你不希望分散用户的注意力在不可理解的代码上,就不该显示出来,干扰用户的认知(它一定会干扰)。第三个论点关于 debug, 前头提到这些代码通常无法 debug,Seymour 在 《mindstorms》里已经非常清晰阐述了 debug 的重要意义。

Scratch 的精髓与积木无关, Blockly 也只是积木的一种实现(当然是最好的实现之一)。 UC Berkeley 的 snap!John Maloney(之前是Scratch的首席程序员) 的 GP Blocks 都不采用 Blockly,但他们才是真正和 Scratch 处在同一层级的东西。

人们通常称这种对代码的积木化包装为糖衣,要我说,这糖衣有毒。 治愈这顽疾的救药是去追溯 Scratch的历史沿革 ,去理解 Smalltalk 社区的深刻想法。 去思考面向对象中封装、抽象和消息通信的观点, 将 vm 看作一种原始汤一样的东西。

建议将 Scratch 称作 图形化编程环境 ,而不是积木化编程环境。


看待 Python 的视角

现代的编程就如同闭着眼睛去排列符号一样 -- Bret Victor

一种不会影响你思考编程方式的语言是不值得学习的。 -- Alan Kay

我受 黑客社区文化 和 Unix社区文化 影响很深,编程生涯成长于这两个社区。与这两个社区有关的书籍,我尤其喜欢:

  • 《Unix 编程艺术》
  • 《黑客: 计算机革命的英雄》
  • 《大教堂与集市》

Python是 Unix 社区的典型项目。

我大约有 8-9 年的 Python 编程经验,但直到在 CodeLab 中完成 Adapter 这个项目,才觉得掌握了它,更确切地说,才觉得自己学会了编程。

在 CodeLab 之前,参与过不少 Python 社区的项目,有些项目还比较大型。

认真读过源码的项目包括:

Adapter 之前, 投入较多时间的 Python 项目是 PaperWeekly。当 PaperWeekly 还是开源社区项目的时候,大多数的早期代码都是我用 Python 写的(如论坛和机器人)。商业化之后,社区项目的后端代码则由我和 @hidaris 以及 @CJ 一同完成。

这些经历确实让我对 Python 的语法和编程相关知识(服务器、数据库、并发、消息队列之类的)比较熟悉。

为了理解这个世界,你必须亲自动手构建它

但我坚持认为通过构建 Adapter(基于Python),我才学会 Python/编程,之前所欠缺的东西并不是知识方面的, 欠缺的是,我此前并不是由热情驱使着去完成自己的项目。倒不是说我之前不喜欢编程,以前也喜欢,喜欢捣鼓计算机,在工作或社区项目中也都很有热情。但那些项目更多是别人的想法,别人想做的事情,而不是我自己非做不可的,这也是我厌恶去解决教科书课后习题的原因,那又不是我感兴趣的。

我之前并没有长时间沉浸在自己的想法里,努力用手中的媒介将其表达出来。

当我在 CodeLab Adapter 项目中,努力表达我的想法时,我发现自己成了一个黑洞,所需的知识从四面八方涌来,为了完成这个项目,我需要不断从周围吸收知识,以下这些东西都曾启发过我:

  • ROS
  • Jupyter
  • Dynamicland/Realtalk
  • ZeroMQ
  • Squeak/Etoys
  • Erlang
  • lively-next

这 Adapter 之前,我在笔记本里也积累了许多编程技巧、算法、设计模式、面向对象、架构笔记,以及许许多多可能用得到的第三方库和项目,想着有朝一日能派上用场,Github著名的 Awesome 系列资源也没少收集。

个人计算对我的影响是,使用计算机去探索你自己感兴趣的东西,把编程当作一种表达媒介,就像铅笔和乐器那样,把你的想法表达出来,在这中间需要什么技巧的话,及时补上就好,不必等所有知识都准备好才上路。 那样你的旅程可能永远不会开始。

为了更好地表达想法,选择那些可以方便表达想法的材料,它们通常具有媒体属性。

在 CodeLab 的 Python 入门课: 交互计算(@麦可)中 ,就充分使用 Scratch 为 Python 引入更多媒介属性。

如果你没有什么想法怎么办?这很正常,开始时很可能就是没啥想法的,你可以随处逛逛,看看社区里的同伴都在做什么,看看周围的朋友有没有好玩的项目,不要放过那些恶作剧的点子(树莓派守护者!)

爱丽丝:请你告诉我,我应该走哪条路?
柴郡猫:那要看你自己想去哪儿。
爱丽丝:去哪儿都无所谓。
柴郡猫:那选择哪条路对你来说也就无所谓了。 --《爱丽丝梦游仙境》

去思考在《终身幼儿园》提倡的 4P:

Projects, Passion, Peers, Play

一旦这把火被点燃,你才真正有能力去做一些伟大的事情...因此,教育的真正意义在于:走出去,去研究许多新的和令人着迷的主题,去学习,去做。最重要的是,找到能点燃你心中那把火的东西。 -- Operating Systems: Three Easy Pieces

我不知道画家或者小说家是不是也是这样,在他全身心投入去做自己感兴趣的事情里时,才真正学会使用手中的笔。在此之前的那些技巧练习,通常乏味且浅薄。

也顺便分享一些学习时可能用得着的资料:

书籍的话,推荐以下两本:

此外,当你遗忘了某些Python知识点,以下材料是不错的查阅手册:

至于 Python 编程环境,我自己特别喜欢 JupyterLabmu-editor

我自己的经历,让我特别认同采用 PBL 教学编程,但光是 PBL 是不够的,学习者如何找到自己的动机,去做对自己有意义的项目,才是关键。

否则只能停留在语法和琐碎技巧的练习里。

关于 CodeLab Adapter

Everything Is a Message.

CodeLab Adapter 是一个由 Python 构建的软件(构建在消息之上(Everything Is a Message)), 致力于连接万物,无论是软件还是硬件,无论是 AI、开源硬件、现实世界的物体、还是虚拟世界的动画角色,接入 CodeLab Adapter,皆可彼此互动。

它能用来干嘛? 玩给你看能给你一些直观印象。

Adapter 是 CodeLab 的基础设施之一。

它支撑了以下项目:

在 CodeLab 工作期间,我把大多数精力投入在 CodeLab Adapter

围绕「更好的 Scratch/Python 编程/创作环境」,付出了近三年的努力,截至目前,交付了还算令人满意的创作环境。我们把在这方面的探索视为对当前领域基础设置的改进:试图扩宽编程/创作环境表达能力的边界,让那些真正有想象力的人不感到拘束。
我们在架构上做了许多思考,这些力量可能还远没有释放出来,等待那些愿意深入其中的探险者。
架构方面的思考,虽然最终实现为代码,但那只是 “更大想法的一个当下截面”,这些想法得益于「个人计算」先驱们的启蒙:采用新的视角看待计算机(动态媒介)和编程(表达方式)。 这些伟大的先驱包括 Alan Kay 、 Seymour Papert 、Bret Victor ...
Alan Kay 教导这种编程风格: “对象通过响应消息彼此通信”,这是 CodeLab Adapter 最主要的设计原则。 --发布 CodeLab Adapter 4.9

之所以采用面向对象、消息风格(Alan Kay的面向对象)风格的架构,是因为我们希望获得晚绑定的能力,希望这个软件是可生长的;

希望未来的新事物,那些在 Adapter 之后出现的事物,也可以加入到这个体系中,我们还希望,编程的孩子可以自己在家里完成这些事情,不需要得到我们的准许,他们拥有的能力和我们是一样的,用户和开发者是一类人:

于是我们关注开放、简易性和可理解性。

CodeLab 成立两年多以来,接待了许多来访者,有技术背景的访客大多对 Adapter 感兴趣(100+), 很可惜的是,大家的兴趣集中在实现机制的细枝末节上,而不是更多去关注设计理念。

技术架构上的讨论当然是有趣的:

架构

但相比于架构和技术实现,更有力的视角关于动机。 诸如为何要接入如此多的硬件,为何费尽心力设计开放接口... 之所以对硬件设备感兴趣, 是因为我们期待:

对现实世界编程

通过硬件,可以与现实世界(物理世界)进行沟通, 接受外部世界的信号(通过传感器),对外部世界施加影响(通过执行器)。 我们希望把整个物理世界纳入进来,将人们的生活卷入进来,让教育成为生活的一部分,这些动机才是我们关心硬件设备的原动力,而技术体系是随时可能调整的,它只是支撑我们这些想法的临时脚手架。

Adapter 前后迭代了 4 个大版本(最新的版本是 4.9),之所以有这么大版本的迭代,是因为在不断干蠢事。每当意识到当前版本多么丑陋和愚蠢时,就想把它丢到垃圾桶里,可用户在用这软件,你不能立刻把它丢到垃圾桶里。这么一来,只好发布一个新的版本,去补救过去干的蠢事。

全世界都在追逐着梦想,查尔斯却在追逐他的噩运。好吧,这两件事其实没那么不同,被梦想俘虏的人就是在追逐自己的噩运…… -- 刘瑜《送你一颗子弹》

每次大版本更新前夕,都非常煎熬。很多痛苦来自 Alan Kay。 他像一位先知,描绘出软件工程的诱人图景,意图推翻整个旧世界。 关于 晚绑定、可生长性、对象与消息、护栏与隔离、统一隐喻的见解,让我确定自己是个彻头彻尾的蠢蛋,看着自己在编程时干过的蠢事 ,羞愧难当。 睡觉的时候、洗澡的时候、上厕所的时候、走路的时候,都在想怎么补救,但没有快捷的救赎之道, 我只能继续阅读更多关于个人计算的观点,以获得看待问题的新视角,争取问出更好的问题,至于答案,去TM的,我现在连什么是好的问题都不知道。 这焦灼又迫切的状态让我一度像个瘾君子。

他(Alan Kay)突然感觉到一股强烈的冲动,想把所有的旧工具都扔掉,从零开始。 -- 《时间机器》

关于 编程教育

我们最初将 CodeLab 使命描述为:

传递编程的乐趣,帮助孩子成为数字时代创造者

后来我们发现,是没有办法帮助孩子学会编程的,于是我们将使命改为:

传递编程的乐趣,鼓励孩子成为数字时代创造者

编程是教不会的。

教不会,我在营造的也是探索的动力和逐渐让他们学会搜索 -- 与 Lounsen 的聊天记录

除非孩子找到自己的动机, 否则他很可能停留在对语法和琐碎技巧的反复练习里。

编程是教不会的,这不是说我们应该躺平啥也不干, 依然有许多有意义的事情可以做,

如果编程环境如此糟糕,教育上的努力,大多得用来抵消这糟糕的编程环境 -- Alan Kay

我们可以改进编程相关基础设施,这正是我们过去投入许多精力做的事情。

我们可以做的,还包括像同伴那样,与 Ta 一起探索编程世界;为 Ta 构造一个宽阔的游乐场: Scratch/Dynamicland;为 Ta 打造一个好玩的俱乐部: Neverland。

但我们也须意识到这些都是外在的事物,如果 Ta 无法在编程中寻找到热情和动机, 无法感受到其中的乐趣,那么 Ta 很可能无法学会编程,如果你赞同编程是一种表达方式的话。

如果他们一时没有找到自己的热情和动机呢?

那就给予他们更多自由和时间。

不要急着用知识去塞满他们,用考核去恐吓他们,也请减少外部激励的剂量,减少这些有毒的短视行为,尽管这短视如此流行。

当你开着一辆车朝悬崖飞驰,别急着琢磨如何开快,比别人开得更快一些的快乐也是短暂的。 悬崖之路的较量,没有胜利者。

给予孩子们时间,让他们自由去寻找内在的驱动力,让他们在线上社区和线下俱乐部里随意闲逛吧。

关于编程教育,我没有更多的好想法,自己也尚在学习之中。 大量阅读 Alan Kay 和 Bret Victor 之后,变得更加不确定编程是什么,却更加沉浸在计算机的世界里,它几乎变得具有无限的可能。

接纳 Alan Kay “计算机科学尚未存在”/“计算机革命不是已经结束,而是尚未开始” 的观点(view point)之后,被一种巨大的荒芜感所冲击,之后却感受到一种漫无边际的自由。 -- 夜行人/aboutme

最后,以两句引语作结:

"计算机科学" 并不是一种科学,而且其重要性也与计算机本身并无太大关系。计算机革命是有关我们如何去思考的方式,以及我们如何去表达我们自己的思考的一个革命。 --《SICP》第一版前言

他(Alan Kay)意识到显然只有那些沉浸在电脑技术和文化之中的人,就像他自己, 才会有满脑子的想法 -- 《时间机器:施乐帕克与计算机时代的黎明》

感谢

除了文章里提到的这些同伴,也感谢一直予以我们鼓励和帮助的人(排名不分先后):

@在梦里、@wangshub、@EricQian、@张佳维、@Tony Yet、@Rick、@邵悦、@Cindy、@zhouF96、@bilikyar、@毛勇、@崔欣、@王中信、@Aihua Chen、@尚祖铭、@M、@tommy、@张印帅、@金磊、@Sean Shao、@JOY、@pigtigger、@熊、@李富荣、@Steven Sun、@song、@Tracy、@苏斌、@韩祝鹏、@李卓泉、@殷悦、@赵老师、@zph、@Shawn、@钟雨辰、@小河、@陈留洋、@陈十一、@CYC、@冯日、@Lyc:)、@罗浩、@Tom Tan、@MobeeHoran、@LLC、@陈坤和、@jingridong、@jingridong、@han-xuefei、@Michael Wu、@刘汉军、@Rhode、@李琦、@RedYin、@刘.泊荣、@okgo、@吴昊、@Hal ...

怕这清单会无穷无尽,就不继续往下列了。

最后, 感谢所有参与 CodeLab 社区和为 CodeLab 贡献过源码的小伙伴们。