喬海燕,周曉聰,楊永紅
(中山大學計算機學院,廣東廣州 510006)
Haskell 函數程序設計基礎是一門面向全校各專業的程序設計入門選修課,采用函數語言Haskell 講授。Haskell 雖然不是業界主流語言,但具有更高的抽象層次,程序設計過程和描述更接近數學,并能使學生更專注于程序設計的基本思想和問題,因此西方許多著名高校采用該語言講解程序設計入門[1]。事實上,設計Haskell的目的之一就是創建一種便于教授程序設計的語言。雖然目前大多數程序設計入門教學使用Python,但筆者認為從編寫正確程序的角度看,Haskell 能給出更好的解。高校選擇講授的語言應該從該語言傳授的思想方法是否鼓勵學生編寫優美正確的程序為出發點,而不是語言的流行程度。以往教學實踐表明,大部分學生學完該課程后表示喜歡函數程序設計的思維方法,欣賞其表現出的簡潔之美[2]。
然而,Haskell 程序設計基礎課程也存在諸多問題,例如部分同學表示學習程序設計具有挑戰性、難度大,涉及到的數學知識難度更大,不少學生在學習初期放棄,還有部分學生因害怕掛科而不選修該門課程。為了克服學生的懼怕心理,并進一步提高教學效果,在中山大學數字化學習平臺BB(Black Board)系統上使用慕課和翻轉課堂線上線下相結合的方式教學,探索Haskell 程序設計教學入門課的有效教學手段,吸引更多學生完成課程學習。
翻轉課堂已廣泛應用于教學實踐,在激發學生學習興趣和提高學習成績方面取得了較好效果[3-4]。例如,何迎生等[5]針對C 語言程序設計教學中遇到的問題,提倡基于慕課的翻轉課堂教學,實踐顯示該種教學方式提高了學生的學習積極性,改變了以往傳統的被動學習模式,提高了學習效率,學生成績也有顯著提高。
目前國內使用Haskell 作為程序設計入門語言的高校并不多,即使在計算機相關專業也較少開設函數程序設計課程。不少學者認為函數程序設計可以更好地培養學生的數學能力,展示程序設計中的許多基本概念,并探討了教學內容設計方法[6-8]。然而,對于選修課,如何通過教學內容和方法的改革吸引學生完成課程,不因課程的挑戰性嚇退學生,并沒有許多文獻或經驗可供借鑒。
中山大學多年來一直開設函數程序設計基礎課,供全校對計算機程序設計有興趣的同學學習。雖然函數程序設計語言并不是業界主流,但其程序設計范式對其他程序設計語言產生了很大影響,例如許多程序設計語言都引入了λ 表達式以及支持函數式程序設計的語法和機制。早期調研顯示,學習函數程序設計有利于初學者理解程序設計的基本知識,便于有一定基礎的學生設計出質量更高的程序[2]。
Haskell 函數程序設計基礎課程每周設置2 學時面對面教學,并在為每位學生配備了計算機的實驗室中進行。該課程一直使用中山大學數字化學習平臺BB 系統發布教學資源、課程信息和在線作業,但并沒有課前可觀看的視頻資源。在教學改革前,BB 系統主要用于發布課程信息和課后作業,學生缺乏主動學習意識。為改進教學,仿照慕課教學模式,為各個教學內容板塊設計和制作了屏幕教學錄像,并配備了相關知識點練習,在課前上傳至BB 系統,供學生觀看和練習。每周2 學時的課堂由教師講解為主轉變為重點解決同學們提出的疑難問題,講解重點和難點,同時鼓勵學生相互交流,提出并回答問題。針對在課堂上不愿意提出問題和回答問題的學生,鼓勵其使用電腦上安裝的電子教室軟件通過發送消息的方式提問或回答問題。實踐證明,多數學生雖然不愿意在課堂上提問或回答問題,但他們可以接受用電子教室軟件相互提問或回答問題。早期調研也顯示,電子教室可以較好地增強師生互動和學生之間的互動[9]。
慕課教學研究表明,制作視頻時有多個因素決定觀看者的投入程度[10],6~9min 的短視頻、教師的激情和較快的語速、視頻與學生的交互等都能更加吸引學生的注意力。為此,本課程組制作了長度適當的短視頻,編寫了可供學生在線學習的題庫,設計了基于BB 系統的類慕課網站[11]。
2.2.1 典型案例設計
在教學過程中通過典型案例使學生感受函數程序設計的美感,激發其學習興趣。函數程序語言更抽象更接近數學,無需考慮與內存相關的概念,只需要在數學抽象層描述計算的邏輯。例如,著名的快速排序算法的計算邏輯用Haskell描述一目了然:
以上代碼表示當輸入是空列表時,計算結果也是空列表;當列表為(x:xs)時,x 是列表的第一個元素,xs 是列表的尾部,則以x 為標準,將xs 的元素劃分為小于x 的列表less 和大于等于x 的列表more,然后分別對less 和more 遞歸排序,最后計算結果為qsort less++[x]++qsort more,其中++表示列表的串接。對于初學者來說,這種簡潔清晰的描述比命令式算法容易理解得多,對命令式語言有一定基礎的學生也會驚訝于這種簡潔之美。
在程序設計中,列表是一類重要的數據結構,掌握列表對象的處理至關重要。為此,本課程就列表數據講解了許多有趣且容易理解的例子,例如將圖形建模為字符列表的字符畫,然后設計字符畫的拼接和旋轉函數。通過這個案例的學習,引導學生發現函數實現過程中的共同計算模式,從而引入高階函數這個函數程序設計的特色。高階函數有趣且容易理解,較好地激發了學生的學習興趣和熱情,進而使其輕松掌握了相關知識。
2.2.2 惰性計算機制帶來模塊化方法
惰性計算是Haskell 函數程序設計的另一個特色,為程序模塊化提供了便利。以牛頓—拉夫遜求平方根的迭代法為例,求非負實數r平方根的迭代公式為:
式中,x0為初值。
對于給定的誤差ε,當相鄰兩個迭代值之差絕對值不超過ε時,迭代即可終止。為此,可以將該任務分成兩個簡單的子任務:①一個生產無窮迭代序列[x0,x1,x2...]的函數;②一個在該迭代序列上選擇滿足近似要求的函數。
任務①可以在x0上反復使用迭代函數f完成,此時:
即序列[x0,f(x0),f(f(x0)),...]可以通過高階函數計算模式repeat 而得:repeat f a=a:repeat f(f a),由此完成第一個任務的計算:
任務②可以用within 函數實現,其不斷檢查列表中兩個相鄰值之差直至這個差值足夠小:
最后,求計算誤差不超過eps 的平方根近似值可以表達為within eps(repeat f x0)。
這個案例很好地展示了惰性計算的魅力:repeat 部分可生成within 需要的數據,雖然repeat 可以生成無窮序列,但是惰性計算機制只需要其生成within 部分需要的數據,一旦within 檢查到符合要求的數據,計算即可終止。這種將復雜問題分解為簡單問題的便利是多數命令式語言不具備的,這便是惰性計算降低復雜度的魅力。
2.2.3 由易到難刷題帶來獲得感
學習程序設計的基本方法是動手編寫程序,使學生有獲得感。為此,本課程設計開發了Haskell 程序評測網站[12],每周推出5~10 個題目供大家練習。在Matrix 系統上布置難度不等的題目,并將一個問題分成由易到難的多個題目。對于每個題目,系統測試設置了多個測試樣例,通過測試樣例數目給學生提交的程序打分。例如,對于歸并排序的實現,首先給出歸并排序方法的描述:
如果輸入為空列表或只有一個元素,則輸出就是輸入(已經有序);
如果輸入xs不空
(1)將xs在中間拆分為兩個子列表xs1和xs2;
(2)將xs1 和xs2 分別排序,排序結果分別是有序列表ys1 和ys2;
(3)將有序列表ys1 和ys2 合并成一個有序列表,這便是xs 的排序結果。
然后將問題分解成兩個任務:
(1)實現歸并函數,將兩個有序列表合并為有序列表的函數:merge::Ord a=>[a]->[a]->[a]
(2)在歸并排序函數merge 基礎上實現歸并排序:mergeSort::Ord a=>[a]->[a]
兩個任務分別完成、分別提交、分別測試。
這種由易到難循序漸進的作業評測方式大大提升了學生們的獲得感,同時激發了其編寫程序的熱情,課堂上程序設計的討論也多了起來,不少同學要求老師布置更多題目。使用Matrix 測評使得學生提交的代碼對老師即刻可見,師生交流更暢通,便于老師有針對性地教學和指導。
在課程進行到10 周左右時進行網上問卷調查,就課程教學情況和同學反饋進行調查統計。實施翻轉課堂的一個重要前提是保證學生在課前觀看視頻。調查結果顯示,47%的學生表示每次都會在課前觀看視頻,39%的學生表示大部分時間會在課前觀看,只有6%的學生表示很少觀看,1%的學生表示基本不看。對于觀看視頻是否對理解課程內容有幫助,54%的學生表示很有幫助,41%的學生表示有些幫助。對于翻轉課堂的感受,17%的學生表示喜歡,63%的學生表示還好,需要適應,也有7%的學生表示反對。
近4 年該課程的完課學生人數和考試成績比較見表1。結果顯示,近年來選修課人數呈增加趨勢(見圖1),且學生成績呈上升趨勢(見圖2)。使用翻轉課堂后,有更多學生完成了課程,而且平時成績增長明顯,反映出學生在平時學習過程中得到了更多幫助,因而能夠堅持完成課程學習,并且投入更多精力完成作業。分析發現,2019 學年期末考試成績低于上學年,原因可能是此次期末考試首次啟用了在線評測系統,系統評測比以往考試評分更嚴格,要求更高。以往期末考試包括部分編寫程序任務,但并沒有提交到在線評測系統。
Table 1 Number of students who completed the course and their grades表1 各學期完課人數和成績
Fig.1 Number of students who completed the course圖1 各學期完成課程人數
Fig.2 Passing rate and excellence rate of students of each term圖2 各學期學生成績及格率和優秀率
開設Haskell 函數程序設計基礎課程的目的是對程序設計感興趣的同學提供入門知識。實踐表明,慕課、翻轉課堂和電子教室等技術手段確實能夠為學習程序設計的學生提供及時幫助,增加師生交流和互動,使更多學生不再畏懼課程難度和掛科等問題,堅持完成課程學習;展示典型案例能使更多學生感受到函數程序設計的美感,有助于激發其學習興趣;評測系統的循序漸進模式增加了學生的編程獲得感,促使其更加深入學習。統計結果顯示,實施線上線下相結合教學的學年,完成課程的學生人數較上學年有所增加,學生平均成績、及格率和優秀率也比往年有較大提高,提示綜合教學手段的應用能有效改善教學效果。