功能完整的 Exercism 軌道有兩種類型的練習:概念練習和實作練習。兩者本質上截然不同,卻能相輔相成。
軌道的概念練習是為了教授特定程式語言基礎的各個概念而設計的練習。這些概念構成一份_教學大綱_。
這份文件提供一些指引和訣竅,說明如何為你的軌道設計出成功的教學大綱。
教學大綱的最終目標,是讓學生能自在地閱讀並撰寫目標語言的慣用程式碼。
每一道概念練習都極度聚焦。它是一小步、方向明確的一步,帶領學生一步步理解這門語言的某個面向。它只建立在先前已經介紹過的概念之上。
透過解題,學生開始熟悉這個概念。理解主要來自動手做,而非講解。說明內容的目的是介紹學生解這道練習所需要的觀念(這也是檔名會取作「introduction.md」的原因)。
我們希望讓學生能立刻開始寫程式,不必事先搞懂所有東西。為了做到這點,我們會含糊帶過一些細節,把很多事情留著不解釋。我們盡可能簡化,並提供程式碼骨架。這能減輕起步時的認知負擔,也留出時間與空間,讓知識慢慢沉澱。採取這種做法,並不代表學生不需要知道這些事,而是說他們還不需要知道。
通常最早的幾道練習必須包含非慣用的程式碼。因為一開始,學生對這門語言的大部分都還很陌生,大多數概念也還沒介紹過。允許最早的練習使用非慣用程式碼,學生就能在熟悉的領域裡多走幾小步,而不是在陌生的領域裡跨出幾大步。結果是他們能更快、更順利地進入慣用程式碼的階段。
練習以樹狀結構組織,最頂端是一道入門練習,作為起點。後面的練習所教授的概念,都建立在先前已理解的概念之上。
看看其他程式語言軌道如何建立它們的概念練習,可能很有價值。你可以在這裡找到其他語言軌道的概念練習範例。
話說回來,如果你決定以其他練習作為自己練習的起點,請務必留意,最後的練習要談的是這個概念在你的語言裡的樣貌。概念有時差異細微,有時則天差地遠。有時某些概念在其他語言裡根本不存在。
教學大綱,連帶概念樹,應該呈現這門特定語言裡確實存在的概念。
不要只因為其他軌道有某個概念,就把它放進來。
有時候,你可能會很想納入某個概念,因為大家經常得用既有的概念來繞過它。與其這麼做,不如介紹這門語言_真正_使用的概念,並考慮加一道練習,說明在這種情況下該怎麼用它。
舉例來說,Go 裡沒有列舉。反之,Go 的概念樹介紹常數,並教你如何在其他語言可能會用列舉的情況裡使用常數。
別猶豫,儘管求助。最好在一開始或在做練習的過程中就發問,而不是等到程式碼審查時才討論。
在 GitHub 上,你可以標註 @exercism/learning-mode 這個團隊。在 Exercism 論壇 的 Exercism Support 分類中開一個議題。
我們的經驗告訴我們,發展教學大綱最務實的做法,是從最簡單的概念開始,讓概念樹自然生長。我們不必事先設計好一切;事實上,不要想得太遠通常反而有幫助。
我們從最基本的概念開始,也就是用這門語言寫出任何東西都最不可或缺的那些概念。我們也盡量從一般開發者最熟悉的概念著手。熟悉是好事。熟悉才不會令人困惑。
記住,終點雖然是寫出慣用程式碼,但通往終點的墊腳石未必都是慣用的。使用熟悉的東西(即使它不是這門語言的好範例)能幫助學生更快朝目標邁進,寫出更貼近這門語言的程式碼。
與其事先規劃整棵概念樹,不如直接從第一道練習開始。第一道練習的目標,是讓學生以盡可能小的阻力開始學習。他們正踏出第一步,開始熟悉這門語言的程式碼長什麼樣子。他們可能會寫一小段程式碼,或只是在骨架裡加上幾行,就完成了練習。學生必須先解過「Hello, World!」,才能進行這道練習。但在「Hello, World!」裡,他們只是改幾個字而已。這門語言的所有語法對他們來說可能都還很陌生。請設法讓他們快速獲得成就感,並熟悉最基本的語法,好讓他們有信心繼續往前。
進一步了解開發第一道練習。
第一道練習應該解鎖幾道介紹基礎概念的練習。這些概念會像是原始型別或基本型別,以及對這些型別做的簡單操作。
進一步了解開發接下來的練習。
這通常是開始變得有趣的地方。到了這個階段,你_可以_介紹的東西實在太多了。你要怎麼決定接下來處理哪些概念?
其實不太重要。只要從看起來合理的地方開始,就沒問題了。
進一步了解我們認為在擴展概念樹時,「合理」代表什麼意思。
好的概念練習極度聚焦,理想上只教一個概念。解題方式通常只會有一種。這和實作練習形成對比,實作練習是開放式的,適合自由探索。
好的概念練習通常是不好的實作練習,反之亦然。由於實作練習和概念練習的目標完全不同,我們不會拿實作練習來改編成概念練習。所有概念練習都是從頭撰寫,或是以專門為了教授簡單概念而打造的故事為基礎。
有時候你會覺得陷入了死結。概念 A 需要先理解概念 B,而 B 又需要先理解 A。
這種時候,就簡化吧。在其中一個概念上含糊帶過一些複雜之處,好讓學生先熟悉另一個。完全可以說某個東西之後會更深入介紹,現在學生只要先搞懂這一小部分就好。
概念是分階段、隨時間慢慢加深理解的。
概念練習一定會有個故事。
如果你是從其他軌道分支一道練習過來,那它已經有故事了。這樣一來,你就萬事俱備了。
想知道有沒有現成的故事可用,或有哪些練習可以分支,請看故事清單。
如果你有概念卻沒有故事,我們建議你先寫一段簡短、簡單、會用到你所介紹概念的程式碼範例。然後再回過頭來,為這段程式碼編一個故事。故事要簡單到不行。它不必是好小說。不需要曲折的情節或角色刻畫。短短幾行也可以。
可以跟 Exercism 團隊聊聊你的故事想法。我們很擅長想出合適的故事。
有了故事之後,你大概需要稍微調整程式碼,讓它配合故事。
投入教學大綱的工作包含兩件各自獨立卻緊密交織的事:
我們發現,讓更廣大的社群一起參與練習的實作,既有趣又能帶來收穫。不過,教學大綱本身的設計,交給一小群貢獻者來處理會比較容易,因為他們全都投入在理解整份教學大綱的種種細節上。
話雖如此,我們建議教學大綱設計團隊先實作出前五、六個概念,再開放社群貢獻。這有助於確保教學大綱設計核心團隊的成員,在必須審查廣大社群送來的 Pull Request 之前,自己已經先了解整個流程。
此外,為這些層次較高的概念建立議題也比較容易,社群成員做起來通常也更有趣,因為要操心的限制比較少。
我們還沒想出建立概念練習時,開議題的最佳方式。
在某些軌道裡,我們試過為概念本身和練習分別建立不同的議題。在其他軌道,我們試過建立附有檢查清單的議題,讓人一項項完成。整體來說,我們覺得這還是太嚇人了,希望能找到更好的做法。
當你開始建立議題時,請和我們聊聊這個流程,我們會盡力協助你找出該怎麼進行。
等我們學到更好的處理方式,會再更新這份文件。