基于字符块的语言与基于文本的语言

基于块的语言与基于文本的语言在许多方面有所不同,这主要是因为它们专为新手用户而设计。以下是设计自己的基于块的语言时需要考虑的事项。

使用从 1 开始编号的列表

用于选择字符串中特定索引处的字母的块,其中 1 表示第一个字母。

新手程序员第一次遇到从零开始编号的列表时,会感到非常不适应。因此,Blockly 遵循 Lua 和 Lambda Moo 的做法,将列表和字符串编号从 1 开始。

为了更高级地使用 Blockly,我们支持从零开始的列表,以便更轻松地转换为文本。对于年龄较小或更为新手的观众,我们仍建议采用从 1 开始编号的编号方式。

建议:1 是第一个数字。

支持宽松的命名规则

变量名称不区分大小写的代码块,例如 location_x(小写 x)和 location_X(大写 X)。

新手程序员不会认为 location_Xlocation_x 是不同的变量。因此,Blockly 遵循 BASIC 和 HTML 的做法,使变量和函数不区分大小写。Scratch 使用更细微的方法(如右侧所示),并且对变量名称区分大小写,但对等式检查不区分大小写。

此外,Blockly 不要求变量和函数符合典型的 [_A-Za-z][_A-Za-z0-9]* 架构。如果想将变量命名为 List of zip codesרשימת מיקודים,那完全没问题。

建议:忽略大小写,允许使用任何名称。

将所有变量设为全局变量

新手程序员也难以理解作用域。因此,Blockly 遵循 Scratch 的做法,将所有变量都设为全局变量。全局变量的唯一缺点是递归更为棘手(必须将变量推送和弹出到列表中),但这是一种超出 Blockly 目标用户范围的编程技术。

建议:范围超出范围,请稍后再处理。

考虑如何处理可选返回值

基于文本的编程中的许多函数都会执行操作,然后返回一个值。此返回值可以使用,也可以不使用。例如,堆栈的 pop() 函数。您可以调用 pop 来获取并移除最后一个元素,也可以调用 pop 来仅移除最后一个元素,并忽略返回值。

var last = stack.pop();  // Get and remove last element.
stack.pop();  // Just remove last element.

基于块的语言通常不擅长忽略返回值。值块必须插入接受该值的某个对象。有几种方法可以解决此问题。

a) 绕开问题。大多数基于块的语言在设计时都会避免出现这些情况。例如,Scratch 中没有同时具有副作用和返回值的任何代码块。

b) 提供两个代码块。如果工具箱中的空间不是问题,一个简单的解决方案是,为每种类型的代码块提供两个,一个带有返回值,一个不带返回值。缺点是,这可能会导致工具箱中包含许多几乎完全相同的块,让人感到困惑。

一个用于移除并返回列表中最后一个项的值块,以及一个仅移除列表中最后一个项的语句块。

c) 修改一个分块。使用下拉菜单、复选框或其他控件,让用户选择是否有返回值。然后,该块会根据其选项更改形状。您可在 Blockly 的列表访问块中查看示例。

移除列表中的最后一项时,形状会从值块更改为语句块的块,具体取决于它是否也返回该项。

d) 使用该值。第一个版本的 App Inventor 创建了一个特殊的管道块,用于吞噬任何关联的值。用户不理解该概念,因此 App Inventor 的第二个版本移除了管道块,而是建议用户将值直接赋给一个一次性变量。

显示两种不同方法来忽略代码块输出的代码块。第一个使用管道块“吃掉”该值,第二个设置名为“junk”的变量的值。

建议:每种策略都有优缺点,请选择最适合您的用户的策略。

生成可读代码

高级 Blockly 用户应该能够查看生成的代码(JavaScript、Python、PHP、Lua、Dart 等),并立即识别出自己编写的程序。这意味着,需要付出额外的努力来确保此机器生成的代码可读。多余的圆括号、数字变量、压缩的空格和冗长的代码模板都会妨碍生成优雅的代码。生成的代码应包含注释,并且应符合 Google 的样式指南

建议:为您生成的代码感到自豪。向用户显示。

接受不同语言之间的差异

追求简洁代码的一个副作用是,Blockly 的行为在很大程度上取决于交叉编译语言的行为方式。最常见的输出语言是 JavaScript,但如果 Blockly 要交叉编译为其他语言,则不应尝试在两种语言中保留完全相同的行为。例如,在 JavaScript 中,空字符串为 false,而在 Lua 中,空字符串为 true。无论目标语言如何,为 Blockly 的代码定义单一行为模式都会导致不可维护的代码,看起来像是从 GWT 编译器中生成的。

建议:Blockly 不是语言,请允许现有语言影响行为。