最近迷上了一些哲史類書籍,回望過去、放眼將來,每每沉浸在其思惟之美中沒法自拔。計算機編程是一門很是年輕的學科,沉澱不足也是年輕的一個側面,在編程領域,有足夠思想深度的做品並很少。這本書的做者老冒我以爲就是一個有深度的人。這周開始,給你們講一下他的好書《冒號課堂》。java
在年末的各大媒體的展望中,我發現編程能力已經悄悄然佔據了比較重要的位置,被認爲是一種影響將來的能力。編程從宏觀上講就是操做計算機工做的方法,而從微觀上講是尋求一種機制,將指定的輸入轉換爲指定的輸出。程序員
可是爲何編程能力是難練成的呢?我以爲最大的問題大於人和計算機的思惟方式是不一樣的,人的思惟追求簡單,而計算機的思惟追求複雜。在這之間有一個巨大的鴻溝,其難點是使用人的思惟來翻譯計算機思惟。算法
編程範式就是這種翻譯方法,它是程序王國的世界觀和方法論,也許是破解編程這門學科的鑰匙。編程
咱們須要從最古老的範式開始,也是編程世界的第一性原理。機器學習
其世界觀是:程序是由若干行動指令組成的有序列表。其方法論是:用變量來存儲數據,用語句來執行指令。函數
這個是由目前計算機的起源,也就是馮·諾依曼機的設計來決定的,也是全部計算機技術的基礎。機器語言就是這樣設計的,也就是說這是計算機惟一能夠直接理解的東西。工具
那是否是能夠有其餘的機器語言呢?理論上固然是能夠的,在早期也是存在的,可是都未有流行。在命令範式中有一個很是重要的推論:oop
任何程序均可以用順序、選擇和循環3種基本控制結構來表示。學習
這也是咱們目前絕大多數語言的實現方式,是平常最爲常見的編程方法。下面是一個範例:人工智能
function getData(col){ var results=[]; for(var i =0; i < n ; i++){ if(col[i]&&col[i].data){ results.push(col[i].data); } } return results; }
你們能夠試一下用語言把這段代碼進行一下解釋,我也找很多同事作過實驗,就算是資深程序員解讀的也不徹底相同,這也說明了命令範式和人的思惟方式有所不一樣,會不太容易理解,如何解決,就須要新的範式了。
上面的那段代碼,究竟是哪裏不容易理解?應該來講是細節的描述過多,由於人的思惟喜歡簡單,而細節是複雜的。因此咱們須要一種不同的描述方法。
命令式編程是行動導向的,算法是顯性而目標是隱性的;聲明式編程是目標驅動的,目前是顯性而算法是隱性的。
命令式編程有幾種不一樣的流派,其中函數範式是如今最爲流行的。
在函數範式中,函數是程序的核心,是頭等公民。
這個說法仍是過於抽象,咱們從上面的例子出發。這段代碼中,最讓人難以理解的應該是for..下面的這段內容,也就是循環段落。在命令範式的三大結構中,咱們會發現惟有循環結構是人在平常表達中不會使用的,這也是計算機複雜性的最重要表現。在聲明式編程的世界觀裏,咱們就須要把這段代碼藏起來。
可是若是隻是採用命令範式中"語句+變量"的表達方式,大概能改進成以下代碼,是好了一點,可是仍是挺讓人費解的。
function getData(col){ var results=[]; doSelect(); return results; } function doSelect(){ results = loop( f-> { if(col[i]&&col[i].data){ results.push(col[i].data); }}); } }
這個時候,咱們就須要對範式進行一下改進了。其實只是一個小改動,擴展一下"變量"的語義:
語句+變量 --> 語句+變量/函數
我想這個也是函數範式名稱的由來,這麼作的效果立竿見影,"變量"複雜了,那麼"語句"就能變的簡單並且通用。咱們能夠把上面這段代碼改進爲以下:
function getData(col){ return col .filter(item=>item&&item.data) .map(item=>item.data); }
是否是可讀性一會兒強了不少,改變只是源於一個小小的思惟上的轉變。以此爲基礎,發展出了許許多多強大的方法和工具,給碼農們提供了強大的支持。讀到這裏,我實際上是有點感動的,這就是思惟的力量。
讓咱們繼續,函數範式把程序的可理解性提高了一截,那思惟探索就中止了麼,固然不會。
命令範式的代碼在理解性方面還有其餘的問題麼?有!
和平常的語言相比,程序的表示老是讓人以爲有些彆扭。以第一行代碼爲例。
function getData(col)
咱們直接讀是"獲取數據 列",挺奇怪的吧。舉一個平常表達的例子會更形象點,程序的表達相似這樣:
吃 牛 草
看出問題了吧,就是缺乏主語。咱們平常的表達中,主語是個不可缺乏的內容,可是在計算機語言中恰恰就沒有。那這句話如何表達才能清晰呢,挺簡單的,換下順序增長主語就能夠。
牛 吃 草
在程序世界裏,給主語起了個名字,叫Object,基於此,誕生了對象範式。這裏有一個很是混淆的地方,就是Object並非主語的意思,並且意思偏偏相反。我以爲這也是對象範式這個概念,始終讓你們很是困惑的一個緣由。這裏只是給一個簡單化的理解方法。
語言表達的改進,帶來的不只僅是理解的提高,更大的改變是能夠將咱們理解正常世界的方法用在理解計算機世界之上,這個化學反應是巨大的。這裏舉一個簡單的例子,就是信息壓縮。
牛 吃 草
牛 喝 水
這兩句話,咱們天然會想到一個壓縮的方法:
牛 { 吃(); 喝水(); }
進一步,又出現了一種新動物,咱們又會想到一種壓縮:
羊 { 吃(); 喝水(); } --> 哺乳動物 { 吃(); 喝水(); }
這就是OO中的封裝和繼承的由來,追求的是簡單,源於平常理解世界的方法。爲何如今對象範式這麼流行,我以爲重要的緣由是其更符合平常思惟,更具備易用性。
今天主要是介紹了《冒號課堂》中講到的最爲基礎的三個範式,從一個小小的改動開始,撬動了一個大大的世界,編程領域博大精深,這只是入門,後面還有更好玩、更有趣的範式等着咱們,下次再繼續探索。 前幾天聽到Google的人工智能專家李飛飛的演講,講到傳統的學習,是用人認識知識,而後再讓機器學習,可是機器學習不同,是把認知知識這一層省掉了,直接讓機器進行學習。這是一種思惟上的大躍進,說實話我還不能徹底理解,但有點能夠肯定的是,思惟上的提高已經刻不容緩,加油。