追求神乎其技的程式設計之道(五)

讓電腦自己寫程式的夢

在高三突然對於讓電腦自己寫程式產生興趣後,我每天就都想著這件事,夢想著未來某一天的電腦能跟我一起寫程式,當我把程式目的說給它聽時,它就一邊把細部的程式碼產生出來:我不用想如何命名變數,或是要用什麼演算法,還是我到底要不要把這個功能變成獨立的class…;我只要動動嘴巴:「我想寫一個橫向捲軸的射擊遊戲。玩家操縱著會變形的飛機,還有四種武器。第一關要長這樣這樣……」,然後電腦就幫我把遊戲寫出來了!如果真的可以這樣,那該有多好啊!(如果真的成真,恐怕我也要失業了?)[註一]

這個想法實在太讓人興奮了,雖然說這是一個遙遠的夢想(其實那時候我並沒有覺得這麼遙遠,只能說自己太不自量力XD),但也開啟我對於人工智慧、程式語言結構、軟體工程等領域的高度興趣。

寫程式很難?

在高中時代頗不知天高地厚的我,一邊嘗試著利用基因演算法(Genetic Algorithms)讓電腦自己產生程式碼,一邊研究各種程式語言的結構和特性。靠直覺摸索出利用tree作為中介來描述一個程式後(那時沒唸過compiler,不知道這個其實就是Abstract Syntax Tree),我突然就對這個想法的可行性信心大增,所以一時衝動就去報名了國際科展,打算把這個想法實做出來。

真的做了以後才發現,最難的部份不是產生出程式碼。如果你把程式語言的基本元素,像是if、for、變數、運算符號等東西做成一塊塊磁體,然後拿給一隻猴子玩,那麼牠其實也能拼出一堆程式給你,問題是:「你要怎麼知道這些程式碼真的達到了你想要的目的?」

悟出這個道理後,我突然了解寫程式最難的部份是在驗證程式碼真的跟你所想表達的事情完全相同。(所以說我對於各家軟體公司的QA地位都低於RD其實感到很不平)

基本上,我們只能設計大量的可能輸入值丟進程式裡,並比對程式跑出來的結果和我們想要的輸出相不相同。即使在這種情況下,我們也只能說這個程式在測試過的這些輸入值上所產生的結果是正確的。也就是說,除非我們測試過所有可能的輸入(這意味著無限多種可能),不然永遠沒辦法知道某個程式是對還是錯。除此之外,即使只測試一個輸入值,也還有個很嚴重的問題:「我們怎麼知道這個程式要跑多久?」換句話說,當你程式跑下去,你怎麼知道他是掉入一個無窮迴圈,還是其實正在拼命計算當中?

我在參加國際科展時,認識了歐陽明教授,他告訴我這個問題叫做Halting problem,Alan Turing在70年前就證明了這是一個無解的問題。知道這件事後,才發現自己所知實在太少,對於資訊科學的基本知識實在非常不足,但這次經驗其實也給了我一個明確的方向,讓我把書中的理論和實際的目標連結在一起。

見樹又見林的學習之道

提到書本中的理論,有很多人問過我要怎麼學習寫程式或資訊相關的知識,我順便在這邊分享些心得給大家參考。

常看到許多人抱怨大學裡學的東西都是理論,畢業後找工作時才發現什麼都不會都得重學;當然企業也會抱怨,大學應該多教一些實務課程,不然出社會後還得重新訓練。說來說去,一致的口徑指向理論和實務是打死也扯不上關係的樣子,尤其念資工的人更常這麼說:「學校為什麼不教C#?為什麼不教我做網頁?好歹也要教個HTML嘛!」


我覺得學習任何事物,一定要有充分的興趣才會有效率,在不知道所學為何的情況下被逼著學習是非常痛苦且沒有效率的。最近看了一本書:沒有資優班,珍視每個孩子的芬蘭教育,書中提到芬蘭教育成功的秘密在於「見樹又見林」,這句話也是我對於如何學習最想分享的秘訣。

台灣的教育方法是「先見樹,再見林」,也就是先教你細部的方法和技術,等你都學會之後(或是硬背起來之後),出社會後就會知道為什麼要學這些東西。(很多人小時候都聽過「等你長大就知道唸書有多重要」吧。可是現在比較多人畢業後反而說「我不知道之前念那麼多書有什麼用」)在這種體制之下,許多人在還沒見到整片森林的美景前就被一棵棵大樹搞得暈頭轉向,痛苦萬分,在不知道「學了這個可以做什麼」的情況下,不管學什麼都會覺得沒有意義沒有動力。

而「見樹又見林」的學習方式,是先找到能引起自己興趣的目標,讓自己有個理由去認真學習,之後再往細部的技術和理論去學習。我從小就很想自己寫遊戲,為了達成這個目標,我就四處尋找相關的資料,慢慢的我就知道自己應該要學好一個快速的低階語言(像是C++),如果要寫繪圖引擎可能還得學一點圖學的理論和技術,如果要做網路連線還得學網路相關的技術…。

這裡有個重點是,不要看過森林後就忘記它,而又迷失在幾棵樹幹上,要讓自己一直重複見樹又見林的過程。

這跟如何有效開發軟體的秘訣是一樣的。一個有效率的軟體開發方式是用iterative process,把包含設計、實做、測試的iteration時間縮短,但要一直不斷重複這個iteration無數次來改進現有的成果。同理,在已經有目標的狀況下學習時,每當學會一些新東西,就要馬上試著把它實現出來,即使是只有幾行程式碼的prototype也沒關係。只要一直不斷的學,這個prototype就會一直被改進,一直加進最新學到的知識和技術而更接近最終的目標。

同時動腦也動手(註二),用這種角度來學習就能充分了解自己學會的東西可以用在什麼地方,馬上得到回饋的成就感還會刺激自己繼續向前進,形成一個非常有效率的學習循環。用這種角度看學校教的東西,就能知道書本上的理論可以用在哪,並且又欠缺哪些實務知識讓自己無法做出想要的東西。

這方法理論上可以擴展到任何事物的學習,重點在找到有興趣的目標和書本裡知識的連結,我覺得這是老師應該要出力的地方,無奈的是台灣的教育體制把中小學老師們變成出考題和改考卷的機器人….。

註一:
其實,現在真的有這樣的研究,而且驚人的是目前已經有了非常接近我想像中未來的雛型。最讓我興奮的是MIT Media Lab的Hugo LiuHenry Lieberman做的Metafor:只要對電腦用英文描述你要的程式,電腦就自動把Python code生出來給你….。

註二:
話說,MIT的校徽上就是一個拿著鎚子的工匠和一個拿著書的學者,所代表的意義就是 “Mind and Hand”,也就是期望每個學生都能手腦並用,除了做夢外也要實做出來才算數啊。

(待續)

15 thoughts on “追求神乎其技的程式設計之道(五)

  1. 你好:

    這篇寫的很棒 感謝你無私的分享

    但台灣的教育是屬於 先見”樹”才見林吧

    你是不是筆誤呢 🙂

  2. Pingback: 追求神乎其技的程式設計之道(六) | vgod’s blog

  3. 我也想過讓電腦寫程式這個問題。

    但這在本質上是否只是在開發「超高階」(極為接近自然語言的)程式語言呢?

    BTW,同意你「見樹又見林」的說法。

  4. Hi jutirain,

    我覺得讓電腦自己寫程式包含很多層面的問題。自然語言只是最上層的溝通、輸入介面,這中間勢必會在經過幾層轉換變成核心層能直接接受的protocol,而「寫程式」這個動作是在核心層裡完成的,這部份應該要能跟上層的輸入介面完全切割開。

    核心層可以只是一種超級人工智慧。舉個例子,我們可以把程式視為一種transformation,給定輸入就會產生某種對應的輸出。那麼核心層的輸入可以只是一些constraints,例如幾組sample input和sample output,接著核心層就能很聰明的找出規律並產生出正確的程式碼…。

    當然這目前只是美好的幻想,我只是想說這個問題本質上是個人工智慧的問題:p

  5. Pingback: 追求神乎其技的程式設計之道(七) | vgod’s blog

  6. Pingback: 寫程式之道 « 凍啡走甜

  7. (所以說我對於各家軟體公司的QA地位都低於RD其實感到很不平)

    Thank you very much. Deeply

  8. 以前對genetic algorithm也有莫名的興趣,做過一番摸索,在lab meeting上找了個genetic algorithm與neuron network如何截長補短、有哪些方式的結合應用與這些方式的優缺點。最後我得到一個心得,就是兩種東西其實都需要人類預先設計好的問題結構知識,才能比較有效的去搜尋合於這問題結構下的問題的答案。How to automatically figure out the problem structure of a problem your program never touched is still a question.

    BTW, 考慮自然語言自動生成code時,個人覺得手寫的圖形語言會比人類口語寫成的句子要更適合生成code,也更適合平行處理應用。畢竟人類口語的結構往往是一維的,圖形語言無論視覺上是二維或三維,planarize後(只要能planarize的話)都是二維的,可以被自動切割成能平行處理的不同段落。

  9. Pingback: 網站製作學習誌 » [Web] 連結分享

  10. Pingback: 好文: 追求神乎其技的程式設計之道 | TechNow 當代科技 - web host by CommuniLink

  11. 前輩,
    看過您的文章,
    深感認同,
    我從小就相信興趣能使學習能力倍增,
    沒想到您高中就已經將c語言摸透~
    另外對於台灣的教育方式我也相當認同你的說法,
    真的該要先以概觀激發學生興趣同時扎根基礎,
    要明白所學何用才對。

    之所以看到您這篇文章,
    是因為我在搜尋”用程式語言撰寫人工智慧”,
    您當初的想法與我現下的想法大抵相同,
    我想得是,
    至少先從初步開始,
    讓電腦依語音辨識執行我要求的工作,
    進階是希望它能自行蒐尋網路並建立資料庫,
    當然我想法在我腦海萌生時,
    這一切已經超出我實質的能力,似乎不可行,但仍有想嘗試的衝動,
    未來必定有很艱辛的路途,仍可努力~
    我看到您提到70年前某位前輩已經證明了什麼理論,
    但我想,那種無窮迴圈的問題應該是可以在條件下控制的~
    感謝您的啟發~
    希望我能持之以恆~哈哈~

留言給我吧!