@Lenciel

少儿编程应该教什么?

目录

<

Shawn 昨天转了个我们友商的 PR 稿给我1

我看不懂第二点,什么叫教研优势「很明突出」,大概打错字了。

然后第三点好像把第一点里面的学得快又说了一遍。

所以加起来应该是说了,他们「广度和深度都更好,并且学习周期还更短」。

作为被拿来对比的公司教研和产品负责人,我想分享一些我对「广度」、「深度」、「学习周期」等等的看法。

然后,算是第一次比较系统地,说一下我认为少儿编程应该教什么。

广度、深度和学得快

我挺喜欢读书和学习。

所以我对下一代应该怎么读书怎么学习,有相当复杂的态度

想要知道点儿什么然后改变点儿什么,大概是我到西瓜工作的核心原因。

在我看来,除非是自以为是的「广度」和「深度」,无论对于小朋友还是成年人而言,都是没法同时去追求的。

广泛的涉猎,更多是解决「为什么」的问题。

深度的钻研,更多是解决「怎么做」的问题。

那么教育公司,应该解决什么问题?

著名计算机学者,图灵奖得主理查德·汉明说过

Education is what, when, and why to do things. Training is how to do it.

我们是一家教育公司。

因此,我们并不把快速地培训小朋友学会「怎么做」作为自己的成就。

作为一名程序员,我也不觉得教这么小的孩子编程「怎么做」是对的事情。

我们关注的是「为什么」和「学什么」,因此,所谓的「有深度」和「周期短」,我们不追求。

如果说具体一点,我们产品的目标,是让小朋友能够掌握一种新的和世界,和各种系统和知识体系进行交互的媒介,让他们更高效地去定位去深入探索自己的感兴趣的领域。

长久以来,人们认为成功需要天赋加上后天的坚持,就像托马斯·爱迪生说的:「天才就是 1% 的灵感加上 99% 的汗水”」。现在,越来越多的研究把「天赋」和「决心」统一到一个东西:对某个主题极度的兴趣。 除非你有足够的数学天赋,否则你不会和拉马努金一样对在石板上研究数列有兴趣,因此兴趣代表了天赋;当你对音乐足够热爱,你也不需要多大决心,就可以像莫扎特一样从六岁开始花十年巡游欧陆,因此兴趣往往带来无需咬牙坚持的决心。

每个孩子都是不一样的,他们的兴趣往往代表着他们与众不同的竞争力。

他们在构建自己的过程中,我们希望常伴左右,我们不是一个「短周期」的培训机构。

但你可能会觉得,大部分家长都会在小学三年级之前,尝试各种各样的「兴趣班」,来识别和培养孩子的特长。

所以,孩子怎么根据自己的兴趣来构建自己,跟计算设备,跟编程有什么关系?

计算设备并不仅仅是工具

计算设备(computing devices)刚出来的时候,只有一个品种,叫做 computer,翻译成「计算机」。现在的计算设备,包括了 PC、笔记本电脑、平板、手机甚至是手表、手环,它们的目的也不再是服务于计算,还叫计算设备全因为人类已经习惯。

这些设备目前还基本都接入了互联网或者物联网。

然而,信息时代,仅仅把计算设备当成工具的人,并不会具备更好的思维能力。

就好像电气时代,仅仅会打开电灯的人不会有好的思维能力一样。

在过去的十多年里,我认识了大几千号的程序员。

我看不出他们作为一个群体,在思考、反思、同理心、思想开明程度等任何人类的认知领域上有明显优势。

甚至很多时候我的感受是相反的:工具的熟练习得带来的是生活里大量错误的认知或者类比。所以相当数量的程序员、科学家、艺术家,相处起来不如你楼下小卖部老板2

这大概是为什么梭罗说:「We have become the tool of our tools.」

工具不带来思维能力,甚至限制思维能力,那么计算设备不是工具是什么?

Alan Kay 在《The early history of Smalltalk》里记录过 1967 年 Marvin Minsky 的一个演讲:

他对传统的教育方法进行了猛烈的抨击,从他那里我第一次听到了 PiagetPapert 的思想。Marvin 的演讲是关于我们如何思考复杂的情况,以及为什么学校真的不是学习这些技能的好地方。很明显,教育和学习必须根据 20 世纪的认知心理学以及优秀思想家的真实想法来重新思考。计算机作为一个新的表示系统,将对处理复杂性,特别是复杂的系统,提供新的和有用的隐喻3

看来人工智能之父在半个多世纪之前就觉得学校无可救药,而计算机可以提供理解复杂系统的「新的和有用的隐喻」。

新的隐喻究竟是什么意思?什么可以形成新的隐喻呢?

新隐喻与新媒介

比喻写得特别好的村上在《海边的卡夫卡》里,有这么一句:

世间万物都是隐喻。

当时我觉得,咦,村上你也读侯世达4

其实很多人都说过类似的话。比如去年过世的 Jonathan Miller

自人类诞生以来,每个人都能感觉到胸部有规律的砰砰声,很多人都看过血管被切断时喷涌而出的血液。但只有在水泵发明后,通过把心脏想象成一个水泵,人们才理解了心脏的功能和血液循环。

既然人类通过隐喻或者说类比来理解和学习世界,是什么限制了我们?或者说,又是什么带来新的隐喻呢?

是媒介。

Eric Havelock 在《童年的消逝》里分析过希腊字母对人类文明的影响。在他看来,这种媒介引发了口头交流时代没有的革命:柏拉图、亚里士多德和其他古希腊人在他们的邻居们的书写系统还只是用来记录国王的生活、谷物的生产、天文的现象时,通过掌握流畅的读写能力,来进行现代化的思考。在过去的30年里,许多学者跟随他的足迹,成功地论证了被称为「希腊奇迹」——如此突然地诞生了民主、逻辑、哲学、历史、戏剧、反省等等——在很大程度上可以归功于字母这个新媒介的发展和传播。

希腊奇迹,不仅仅是古希腊产生了新的书写和阅读工具,更重要的是,产生了哲学的、科学的、历史的、法律的和道德的,基于新的媒介的新的思维方式。

这些思维方式贯穿了写作和阅读,写作和阅读又继续强化这些思维,最终形成了我们所谓的现代思维。

联网的计算设备是怎样的媒介

新媒介会带来新的思维方式。

在没有文字的文化中,人类的记忆是最重要的媒介。谚语、诗歌和故事包含了世代相传的口头智慧。

所以当刚刚有文字的时候,最智慧的人还是孔子或者所罗门:在《论语》或者《列王纪上》里,崇拜者整理了他们(或者是别人)的箴言。

但是一旦文字系统得到升级,特别是有了印刷技术,记忆或者说记得多少不再是关键,写作者也开始追求逻辑的组织和系统的分析,而不是谚语箴言里单薄的智慧。

每一种媒介,看起来给我们携带的是无差别的信息:从书籍到电报,从电报到电视,从电视到网络。但每一种媒介,都会潜移默化地改变人们的思维方式:我们如何使用我们的身体,我们如何理解这个世界,我们如何构建我们的观念。

这就是 Marshall McLuhan 说的「媒介即信息」的实质。

那么,计算设备究竟是怎样的一种媒介呢?

不容乐观的现状

关于联网计算设备这个新媒介对人类的影响,各种批判已经太多了

每个人,应该都能感到它对人类思维方式的改变。

我讲几个我担心的点。

一个是劣币驱逐良币。比如个性化的推送,让你的偏好或者偏见在被无限循环地加强。比如八卦过多:各种网站、App 和微信群提供了无穷无尽的八卦,人很难不去关注,因为这是人类基因里的需求。但我们基因里有八卦的需求,是因为它取代了猩猩时期的互相梳理毛发。通过分享和接收八卦,你在另一个人之间建立了一种社会联系。然而,当少数人通过新媒介以夺取我们注意力为目的,疯狂地异步地提供流言时会发生什么呢?没有任何有意义的关系被建立。再比如,大量的暴戾的无知的攻击在泛滥,真正有意义的批评在消失,甚至真正有意义的观点也在消失。

一个是隐私的丧失,和随之而来的诚实的丧失。当我们在网上的时候,展示的是我们希望被认同的东西: 我讨厌它这种强制的表演成分。无时无刻不在的新媒介的问题是,这种表演性的生活,以前只需要那些真正生活在公共场合的人——明星、名人、政治家——承担,现在成了全人类的负担,因为只要在网上,就是在公共场合。人人无时无刻地在模仿和学习,网络上到处是的高谈阔论和赞美诗。实际上,没有隐私就没有诚实,而隐私不像我们的手和脚,它是一个概念,于是保护起来就更难:什么是隐私,已经不是自己说了算。

最后是随便谁都能说一嘴的、口头交流的社会的回归。人类社会形成已经有20万年的历史了,但是在大部分时间里,作为一个社会,几乎没有什么事情可以被认为是进步的。直到几百年前,出现了科学思维。科学需要一个社会到一定的文明程度才会出现,因为再优秀的个体,也只喜欢自己认定的思想和理论,从而因此陷入圈套ーー大部分调试工作必须由他人完成。但是,为了使社会发挥这样的作用,整个系统必须超越我们的基因缺陷,以一种原则去运作。过去的几十年,新的媒介已经代替了大量日常的阅读和写作,使得世界重回口头社会:如果我们的目标是大多数公民能以现代化的思维去思考,而不是回到希腊之前的状态,这根本不是一件好事。

对于大多数人来说,和这个新的媒介建立的连接,都是相当有害的。

那我们要怎么做?

理解认知发展的一个问题是,我们没有足够的隐喻来描述它。我们可以把心脏想象成水泵,但我们的认知是什么?Piaget 的四阶段是最著名的以生物发展为隐喻的阐述,John Dewey 提出了一个以 growth 为基础的体系。但它们都不够好。

计算设备作为一种新媒介,能带来什么新的隐喻?

计算设备里,构建世界的成本很低,互动性很好,反馈很快。Feynman 说,「What I cannot create, I do not understand」,它会是一个可以让人更好地参与 create 的媒介吗?

再想想下棋,比如围棋。当你学习围棋时,首先要学会很多规则,来从小局部去阅读棋子的组合:黑色在这里,白色在那里,往哪里下是可以的,往哪里下是有利的。

然后,随着你的水平逐渐提高,就要学会从远处看:你不是 alpha go,无法进行全局的计算,从远处看的时候,使用的是直觉。

围棋,以及很多类似的东西,都是当思维复杂度趋于极限,我们的脑子就要开始变得紊乱的情况下,逼我们调动两种截然不同的思维方式。

离散和连续。

理性和直觉。

计算设备可以让我们更好地应对复杂度从而更深刻地理解世界吗?

我还没有答案,但我隐约觉得我们的产品应该是有一个硬件的。

搞了一些硬件

但学习编程和掌握计算设备媒介之间的区别是显而易见的:就跟学习阅读和写字,跟掌握写文章之间的区别一样大5

语言是用来阅读和写作的,但思想才是关键。

所以,困难不在于让孩子们喜欢我们做的课程,或者学会编程。孩子喜欢任何课程,因为他们喜欢做事情,即使他们不知道自己到底在做什么。当我们给他一个计算设备,他会尤其喜欢,因为反馈太快了,他可以跳过做其他事情需要的大量基本动作的枯燥练习。

困难的是要确定在一个小朋友具体出于什么发展水平上,然后根据他的水平,提供什么样的内容,渗透什么样的想法,渗透到什么程度。尽管已经有了几个世纪的经验,我们可以看到在阅读、写作、数学等等领域,这个困难仍然存在:什么时候,以什么样的顺序和深度,以及什么形式,来传授伟大的思想?

什么叫做掌握了一种新的媒介?当他们听到新冠这样的瘟疫,能立即知道这种灾难的指数特征以及早期行动的重要性。然后他们来到计算设备前,可以流畅地建立一个疾病的模拟系统,并用它来跟接下来真实世界里发生的数据进行比较,从而理解它。

印刷机是工具,但书不是。

钢琴是工具,但音乐不是。

我希望我们的产品让孩子们能够深刻而流畅地把计算设备作为媒介去掌握,就像文学、数学、科学、音乐一样,成为他们理解这个世界,与这个世界交互的能力。

我希望我们的小朋友能「code to learn」,而不是「learn to code」。

  1. 如果非要我评价,我想起歌德说:「探索中的同行者,应该学会分享发现的喜悦,而不是徒劳地宣称自己比别人干得更好」。但人类,即使是优秀的人类,也很容易被自己局限,情绪、认知、格局。所以,牛顿曾经劝大家,直接站到巨人的肩膀上去,就看得更远。但在互联网或者广义地说,在整个技术产业里,现实情况是大家常常站在,或者说是踩在彼此的脚背上。认真地研究,开放地分享,不断地进取,可能是更好的态度。 

  2. 其实如果我按照自己的标准衡量的话,很多专业人士对自己专业内的认知和对生活的认知一样糟糕。 

  3. Alan Kay 去听 Minsky 讲 Papert 和 Piaget 对自己的影响,这件事情本身可能就说明了为什么现有的计算机科学的理论都是在上个世纪 60 年代左右奠定的,后续更多只是工程上的优化:因为当时没有人是「计算机科学家」。 每个参与其中的人都带着许多其他的知识和兴趣参与其中,他们有研究认知的,有研究物理的,有研究数学的,然后他们试图搞明白「计算机是什么」,他们用大量其他领域的东西来进行类比。而一旦进入工程领域,就很难有范式上的创新。因为工程就是关于优化的,如果没有牢牢地锚定在所处的上下文中,就谈不上如何优化。 

  4. 侯世达有本书叫《表象与本质 : 类比,思考之源和思维之火》,他还有篇文章,名字就叫 Analogy as the Core of Cognition。他的书读起来很有意思,有空可以专门写一下。 

  5. 浙江今年满分作文引起的争议说明了,文字和句法只是形式,文章里面的思想才是关键。但思想只能通过思想产生,好的思想产生更好的思想。如果我们在一个不允许思想产生的环境里强调文字,我们就会得到这样的满分作文。这不是孩子的问题,这也不是老师的问题,这是体制的问题。在我看来合格的语文教育就是让学生可以随便找一个《人民日报》的社论,然后写出一篇观点清晰的文章对它进行批评或者辩护。 

Python in 2020 (4) - 类型检查

编程语音的类型系统其实是非常重要的。

但作为一种弱类型语言,Python 的类型检查是非常困难的。但自从 3.5 版本加入了 type annotation,很多工具变得强大了起来。

目前,mypy 是这个领域最值得关注的。几个大厂也各自有自己的实现[^1],有些 IDE 比如 PyCharm 还自带一个类型检查工具,但这里主要说一下 mypy 的使用。

目录

静态类型检查

安装 mypy:

$ poetry add --dev mypy

在 Nox 里面添加一个 session:

@nox.session(python=["3.8", "3.7"])
def mypy(session):
    args = session.posargs or locations
    install_with_constraints(session, "mypy")
    session.run("mypy", *args)

然后就可以运行了:

$ nox -rs mypy

为了控制可以编辑 ‌mypy.ini 配置文件,比如:

# mypy.ini
[mypy]

[mypy-nox.*,pytest]
ignore_missing_imports = True

类型声明和检查

如果类型检查只是装个工具扫描现有的类型意义就不大了。它更大的作用是支持自定义类型并检查。

假设我们有下面这样的函数,返回的是一个页面的 json 格式对象:

def get_page(): ...

我们想要给它声明一个类型,但它不是 Python 自带的 str/list/dict 等类型可以覆盖的,所以我们可以声明为一个使用 dataclasses 定义的 Page:

from dataclasses import dataclass


@dataclass
class Page:
    title: str
    extract: str

def get_page() -> Page: ...

那么,在测试的时候如何进行 Page 的构造呢?可以使用 marshallowdessert 。前者是一个数据序列化/反序列化的工具,后者则是以 marshallow 打底使用 dataclass 的 annotation 生成序列化 schema 的工具。

安装:

$ poetry add desert marshmallow

添加依赖:

# mypy.ini
[mypy-desert,marshmallow,nox.*,pytest]
ignore_missing_imports = True

这样我们就可以代码里面使用 dessert :

from dataclasses import dataclass

import click
import desert
import marshmallow
import requests


API_URL: str = "https://test.com/api/rest_v1/page/random/summary"


@dataclass
class Page:
    title: str
    extract: str


schema = desert.schema(Page, meta={"unknown": marshmallow.EXCLUDE})


def get_page() -> Page:
    url = API_URL.format()

    try:
        with requests.get(url) as response:
            response.raise_for_status()
            data = response.json()
            return schema.load(data)
    except (requests.RequestException, marshmallow.ValidationError) as error:
        message = str(error)
        raise click.ClickException(message)

这样在测试中也就可以直接进行类型检查了:

# tests/test_get_page.py
def test_get_page(mock_requests_get):
    page = test.get_page()
    assert isinstance(page, test.Page)