入门编程:D语言是否适合初学者?

发表时间: 2022-04-06 10:57
译者 | 弯月
出品 | CSDN(ID:CSDNnews)
大约两年前,我儿子的一个小伙伴问我是否可以教他们学习编程。我的两个孩子都对 Scratch 编程充满了兴趣,而且我也需要考虑分担一下家庭教育的重任,因为两个孩子的教育主要由我老婆担当。所以我就想,可以啊,教孩子们学编程也不会太难。然而,在过去几年中,我遇到的困难远远超过了预期!
首先,简单地介绍一下本人。我从事专业的软件开发已经 20 多年了,工作中使用的编程语言是系统语言和 Web 开发兼半。我从事过许多编程项目,其中包括 256 字节 RAM 的嵌入式微控制器、使用高端 Unix 工作站的协作视频系统,以及自动化工厂测试机架上的设备。我没有任何编程教学相关的学位。当然,这对我来说是一个新奇的挑战,而且我也觉得非常有成就感。
再说一说孩子们。我有 10 名学生,年龄在 9~15 岁之间,他们都没有真正编写软件的经验。由于这门课只是我利用业余时间开发的一个业余项目,因此我们的进展很缓慢,大约每两周上一次课。
我这个学习班的目标之一是,尽量不要将编程简化为抽象。我想让孩子们体验真正的编程,而且不需要接触太多框架。我观看了一些在线编程教学视频,这些资源隐藏了大部分的实际工作,只专注于使用自定义库或简化语言来学习“基础知识”,实际上并未介绍标准的工作环境。我亲眼目睹了自己的孩子在看到教学材料进展太慢或太抽象时就会觉得无聊。


第一次尝试:Javascript 和 Lua
第一次我选用的语言是 Javascript,因为许多孩子没有真正可用于开发的计算机。Javascript 可以在浏览器中开发,使用平板电脑或 Chromebook 都可以,这样班上所有的孩子都可以正常学习。
刚开始的时候,我介绍的重点是基本概念,如循环、分支和基本语句。我认为 Javascript 作为入门级的编程语言是很不错的,尽管作为初学者可以用它实现的功能有点乏味,而且如果想实现一些有趣的功能,就必须学习 DOM(包括对象和方法的工作原理)。
半年后,我们开始学习第二门语言:Lua,特别是在视频游戏系统 Roblox 中。其实,我很希望跳过这门语言,因为对这些学生来说这门语言有点太高级了,而且我不太熟悉这门语言和系统。孩子们对模型构建的用户界面很感兴趣。但是,我发现一位经验丰富的老师找到了使用这种环境开展教学的好方法。Roblox 拥有预先构建的渲染和物理引擎,可以让孩子们使用相对较少的代码生成非常酷的游戏,这也是编程新手非常喜欢的方式。

D语言

到了第二年,我决定尝试教孩子们学习我最熟悉的语言:D 语言。由于所有孩子都对构建游戏有着浓厚的兴趣,因此我搜索了一下可用于构建游戏的库。我必须对库 Raylib 和 YouTuber Ki Rill 表示由衷的感谢,这两个库非常简单,而且视频的制作非常用心,因此我相信我的教学中可以使用二者。
为了快速演示 Raylib,我花了几分钟编写了一个小程序,用 Raylib 绘制了一个小D(https://github.com/schveiguy/dman)。
班上的每个孩子使用的都是 Windows,所以我为他们准备的工具链是:DMD 编译器和带有 code-d 扩展的 Visual Studio Code 开发环境。在过去的去一年半里,我让孩子们使用基于文本的“图形”构建了多款经典的小游戏,比如猜单词游戏、井字游戏等。后来,我又向他们介绍了二维图形和 Raylib,并构建了一个类似于打砖块的小游戏。
最后,我让学生选择自己喜欢的游戏作为结业项目,他们选择的是石头剪刀布。我不太明白这个游戏有什么魔力能够长盛不衰……
别忘了我的目标是教他们编程,而不是 D 语言。通过这些项目,我向孩子们介绍了许多经典的编程概念(分支、循环、函数、数据类型、数组等)。今年,我们主要介绍了聚合(特别是数组和结构),以及如何利用它们封装解决方案。此外,我们还编写了贪吃蛇。我希望在年底前完成这些工作,并于明年开始介绍网络,这样孩子们就可以编写在线游戏了(现在所有的孩子都喜欢在线对抗类游戏)。

D语言教学的心得分享

作为入门,D 语言究竟如何呢?我可以自信地说,孩子们不仅理解了 D 语言,还学习其他语言的基础知识。由于 D 语言是他们接触的第一种类型语言,所以首先我必须解释类型是什么,以及为什么类型很重要。此外,我必须挑选 D 语言中不会造成混淆的概念。为此,我略过了许多高级功能,例如:
● 模板
● 类型推断
● 运算符重载
● 通常意义上的重载
● __traits
● 类/接口/OOP
● 指针/引用(大部分)
● 通常意义上的内存管理(感谢 GC!)
这意味着,我介绍的 D 语言缺少很多语言特性,尽管我个人特别喜欢其中的很多特性。但我不得不在教学中避开这些特性,以免孩子们感到困惑。此外,我也希望尽量避免走捷径,因为我希望他们在学习如何更快地编写代码之前,首先掌握基本的概念。例如,我努力尝试使用花括号将作用域括起来,而没有采用单行的语句。
我发现孩子们处理得很好的特性是基本类型,如整数和字符串(尽管“字符串”这个名字值得回味,但他们需要过一段时间才能理解)、if 语句和 foreach/while 循环、结构和函数。他们很难理解数组和关联数组,这可能是由于我缺乏教学经验。我还要指出,虚拟教学面临着一些重大的挑战,不只是你无法走到孩子身边帮助他们,或者是无法在白板上画出数据的布局方式,虚拟教学无法替代面对面的交流。但是,他们能够从容地处理嵌套函数,这让我感到十分惊喜。这是 D 语言中的一个很好的特性, C 中没有,C++ 中也几乎没有,而且我个人花了一段时间才习惯。


问题反思

问题多到不胜枚举。首先,我必须时刻谨记对编程一无所知是什么感觉。我没有参加过任何编程教学的课程,也没有寻找“正确”的教学方式,只是根据孩子们的技术和经验选择了最好的方法。每两周上一次课也是一个大问题,因为孩子们需要回忆上次课程的内容。当然,每天或每周两次的课程安排会更好些,只可惜我没有那么多时间来备课。
其次,我没有游戏编程的经验。好在有了 Raylib 的帮助,只要能理解事件循环,就会非常简单易懂,而且很有趣。
除了个人和环境的问题,我还有一些给 D 语言和社区的建议,为的是让 D 语言成为更好的“入门语言”。以下建议没有特定的顺序:

错误信息

D中的错误消息有时非常难懂,我指的不只是模板。孩子最常犯的错误是标点问题。而 D 会给出一堆乱七八糟的消息。大多数时候,我需要解释发生了什么,但即使我自己有时也会被编译器迷惑。例如,如果忘记分号:
void main(){
import std.stdio;
int x = 5
writeln(x); // line 5
}
就会得到如下错误信息:
foo.d(5): Error: semicolon expected, not `writeln`
可是,第5行明明有分号!为什么会出问题呢?理论上,只需在第 5 行的 writeln 调用之前添加一个分号即可解决这个错误(毕竟,D 中的空格没有实际意义)。但实际上,编译器不应该建议这样做。
我觉得以下错误信息会更好:
foo.d(5): Error: previous statement not terminated, perhaps youneed
a semicolon on line 4?
如果少一个或多一个括号,怎么办呢?编译器会给出一堆难懂的错误信息。我知道这不是一个容易解决的问题,但由于编译器不涉及棘手的语义部分,如果通过源代码的其他提示来给出解决方案,会怎么样?比如通过缩进获取提示。
D编译器的一个重要功能是检查拼写,并给出更正建议。但有时,很难看出给出的建议究竟想更正哪个拼写(尤其是当大小写不同时)。为什么不突出显示应该更正的字母?既然 D 语言使用不同的颜色输出错误信息,我认为可以让输出更加清晰。
我必须转达一个学生的评论,他说他很喜欢 VS Code 的一个功能:跳转到编译器报错所指的那一行。这可以让我们看出他们的感受。

Windows上的 VSCode 调试器

我面临的另一个挑战是,Windows 上缺乏良好的 VS Code 调试体验。例如,在 VS Code 中,C 语言的调试器会显示一个字符串的长度和一个C风格的字符串(可能由于结束符问题而显示一堆垃圾)。我不希望这些信息让孩子们感到迷惑。我知道 Visual D 有更好的调试体验,但这些项目需要 Dub 支持,而 Visual D 只能与 Visual Studio 集成,我不想在教这些孩子时掺和这些问题。
我认为 WebFreak 的 VS Code 插件非常好用,而且在大多数情况下,运行良好。谢谢!我知道调试是一件很难的事情。

外部库的链接

我遇到的难题还有一个,使用Dub进行链接。如果你只使用 D 和 OS 提供的库,那么 Dub 非常棒。然而,如果你需要依赖操作系统之外的 C 库(例如 Raylib),那么不仅需要添加依赖项,还要下载预构建的库,或者自己动手构建。虽然对此我没有很好的建议,但我希望通过某种方式告诉 Dub 从哪里下载这些库,或者有一个中心仓库来存放这些库,以方便链接器在 dub.json文件指定的路径之外找到这些库。许多库都在 GitHub 上,因此可以将 GitHub 作为下载和安装外部库的主要来源。
我花了大量时间帮助孩子们搭建环境,如果能内置到 IDE 或 Dub 中,对 D 语言的教学会有非常大的帮助。


今后的建议


我相信 D 可以成为入门级的编程语言。在我的班上,有些孩子从未编写过真正的代码,但现在也能够使用 D 和 Raylib 创建二维游戏(尽管需要大量的手把手教学)。我认为 D 语言想进一步扩大这种成功的案例,就需要提供一组面向新手的学习资源。D 的大部分学习资源旨在教授有经验的程序员如何根据已有的知识使用 D 语言编程。这些资源解决的问题是:“如何在D语言中实现某个语言的某个功能?”但我需要解决的问题是:“如何编写代码”,而且还是使用 D 语言。
这些资源的创建应该不难,因为 C 语言编程的学习资源非常丰富。而 D 与 C 非常相似,二者几乎可以互换。
最后,这些资料必须富有吸引力!在学习编程时,做一些有趣的项目非常重要。兴趣能够让孩子们更加投入,与编写简单的 hello world 程序或 Javascript 页面相比,编写出自己喜欢的游戏更能激发孩子的兴趣。一种很好方式是,用 D 语言编写一个游戏,然后再引入其他特性,改进代码。
我希望这些建议能够实现,因为我认为该领域的开发大部分集中在一些降低学习门槛的框架上,从而让孩子们也能够学习编程,或者是一些纯粹的 hello world 级别的千篇一律的教学上。我认为我们应该尽可能展示 D 的潜力,通过有趣的项目吸引热心的学习人员,引导他们使用我们最喜欢的语言学习编程!
参考链接:
https://dlang.org/blog/2021/12/23/teaching-d-from-scratch-is-it-a-viable-first-language/

END


新程序员001-004》全面上市,对话世界级大师,报道中国IT行业创新创造


成就一亿技术人