迭代算法
對於函數是 first-class 的語言來講,迭代的變形不少,從 Python 的 Comprehensive 到, Perl 的 map, 迭代是最能體會函數式語言威力的地方。編程
[ x * 5 for x in [1,2,3,4] ] (map (fn (x) (* x 5)) [1,2,3,4]) map { $_ * 5 } (1 .. 5);
while 守衛循環數組
while 循環是設置一個條件,內部循環執行一段代碼,而且設置迭代變量。網絡
while ($x > 1) { last if $x == 10; say($x); $x++; }
在 while 條件表達式中的變量是外部的,反覆執行代碼部分屬於內部,但做用於同一個變量。數據結構
還有一種 while 守衛循環是在內部賦值:多線程
{ my $x = 0; $x++; } until ($x > 10);
其實,只要保護好變量不被意外賦值,兩種形式都是能夠互相轉換的。閉包
並行循環函數
在支持並行的語言中,若是循環和順序無關,彼此之間的計算結果沒有前後依存關係,就可使用並行循環。並行循環充分利用多核的計算資源,能明顯提升代碼的效率。線程
線程或進程設計
多個結果不互相依存的計算過程,尤爲是網絡讀寫這種耗時較長的工做,一般同時用許多獨立的線程來完成,以充分利用等待的時間段,多作些工做。爲了蒐集和容納這些進程的工做結果,一般會用到隊列。
隊列是一種特別的數據結構,有點像數組,但又有時間上的限制,防止死鎖進程致使的程序終止。有一些容錯機制。
有了多線程的計算模型,代碼更像是一個調度,分別監控各個獨立的計算模型運行結果,彼此溝通,並對結果進行判斷,處理意外。這是一種更高級的編程模型,裏面同時容納多個獨立運行的代碼,分別管理分配不一樣的變量表和命名空間。
函數
函數是最普遍應用的一種代碼抽象,他把重複運行的代碼片斷進行命名,抽象出參數和計算過程。
大部分函數返回的參數都是一個, Lua, Golang 能夠返回多個,Python 利用元組也能模擬返回多值。函數的自由變量,一般是在定義的位置,獲取外部變量的值。爲了隔絕這種外部變量,有了閉包的概念。
Javascript 沒有塊級做用域,因此他的閉包實現是用函數中的函數實現的,這也是一種沒有辦法的事情。但被人用來炫耀這種技能,這實際上是一種錯誤的語言設計致使的一種變態作法!Python 也是如此,爲了增長閉包的功能,增長了 global, nolocal 兩個關鍵字才勉強實現。
Lisp 的函數做用域是動態的,和 Scheme 不一樣,也就是從 caller 來獲取自由變量的值。關於這種設計有不少爭論。但我認爲,自由變量的存在,自己就是一種錯誤的設計,由此引起的語言特性的爭論,不過是在裂縫上塗泥巴,顏色不一樣罷了。
命名空間
命名空間讓變量,函數的命名更加簡單,寬容。C 語言是沒有命名空間的。C++ 增長了命名空間,也添加了類。
命名空間彼此之間的變量名稱是互相隔離的,即便是在一個命名空間內定義別的命名空間,也是如此。
命名空間從名字上能夠有歸屬關係,但實現並非嵌套,只是和平行的命名空間有不一樣的名字繼承原則,彼此之間是互相獨立的。
不一樣的語言有不一樣的命名空間符號導入導出原則。Java 用 public, private 來界定導入導出的權限,而 Golang 則默認使用首字母大寫的符號做爲 public 符號。
類的實質是命名空間,能使用這裏定義的函數,一定是由這個類定義的一個數據結構模板生成的。只是調用其中的函數是用另一種句法:
my $obect = new Class_name $object->method(args);
由於實際上函數調用,傳入的多了一個參數,就是對象自己。類沒有名字導出,全部可調用的函數,都是經過對象調用的,只有不能調用的方法,沒有能夠導出的方法。
類中定義的函數,又叫方法,由於處理的第一個參數,老是固定數據結構的對象,因此有些語言就乾脆省略,用 self 代替,由此方法和函數使用不一樣的關鍵字。
默認,類和其子類有繼承方法的原則,這樣一個類可能擁有的方法可能來自不少,這讓類設計很容易變得複雜而龐大,由於檢索一層層的方法而讓面向對象的語言的速度下降。
即便量子計算機和神經元計算機面世,更大的需求出現,計算機能作的事情也變化不大,只是處理的數據多了些,硬件快了些,算法複雜了些罷了。