以區塊為基礎的語言與以文字為基礎的語言有許多不同之處,主要是因為前者是專為新手設計。以下是設計自有區塊式語言時應考量的事項清單。
使用一維清單
初學程式設計人員第一次遇到以零為基底的清單時,會感到相當困惑。因此,Blockly 會追隨 Lua 和 Lambda Moo 的做法,讓清單和字串索引值以 1 為基底。
為了讓 Blockly 的進階用途更完善,我們支援以零為基點的清單,方便您轉換為文字。對於年輕或新手觀眾,我們仍建議採用單一索引。
建議:一是第一個數字。
支援自由命名規則
初學程式設計的使用者不會認為 location_X
和 location_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 第二版移除了管道區塊,並建議使用者直接將值指派給一次性變數。
建議:每種策略都有優缺點,請選擇最適合使用者的做法。
產生可讀的程式碼
進階 Blockly 使用者應可查看產生的程式碼 (JavaScript、Python、PHP、Lua、Dart 等),並立即辨識自己編寫的程式。因此,您必須額外付出努力,才能讓機器產生的程式碼易於閱讀。多餘的括號、數字變數、壓縮的空白和冗長的程式碼範本,都會影響產生優雅程式碼的過程。產生的程式碼應包含註解,並符合 Google 的樣式指南。
建議:歡迎您使用產生的程式碼。向使用者顯示。
接受不同語言之間的差異
由於我們希望程式碼簡潔,Blockly 的行為大多是根據交叉編譯語言的行為定義。最常見的輸出語言是 JavaScript,但如果 Blockly 要跨編譯為其他語言,則不應採取不合理的做法,以便在兩種語言中保留確切的行為。舉例來說,在 JavaScript 中,空字串為 false,但在 Lua 中為 true。無論目標語言為何,為 Blockly 程式碼定義單一行為模式,都會導致無法維護的程式碼,這類程式碼看起來就像是 GWT 編譯器產生的。
建議:Blockly 並非一種語言,請讓現有語言影響行為。