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