- Julia機器學習核心編程:人人可用的高性能科學計算
- 朱紅慶
- 3093字
- 2020-07-28 11:01:33
2.1 重溫編程范式
一般來說,解決問題的思路是先找出問題的來源,然后將問題分解成若干個小問題逐一解決。同時,還需要考慮所有情況,以保證該方法能完整地解決問題。而編程范式就是一種將編程活動分解的思想,雖然編程范式有很多種,但一種范式可能更適合解決某一類問題。
在這里只討論命令式、邏輯式、函數式和面向對象的編程范式。
建議大家理解編程范式,因為一種編程語言可能適合使用一種特定的范式。例如:C語言適合使用命令式編程范式、Haskell適合使用函數式編程范式、Smalltalk適合使用面向對象的編程范式。下面具體介紹這些不同的編程范式。
2.1.1 命令式編程范式
命令式編程范式是一種程序化的編程方式,它主要關注的是變量和可能會改變這些變量值的語句(代碼段)的順序執行過程。這種范式基于馮·諾依曼計算機,其具有可重復使用的內存,并且允許改變這塊內存的狀態。
命令式編程范式假設計算機能夠維持在計算過程中生成的變量的不同狀態。對于命令式編程范式而言,程序執行的順序非常重要,如果更改語句順序,則可能會產生不同的狀態和結果。
在程序運行過程中,計算變量的狀態是程序中定義的變量的當前值、將要執行的下一個任務或語句以及任何活動子程序所期望調用的數據。以上這些是可以改變程序狀態的因素,因此命令式編程范式可以被理解為一種連續執行語句的范式。
使用命令式編程范式具有如下優勢:
? 能有效地利用系統資源。
? 基于計算機的運行方式,因此與機器語言相近。
? 很多流行的語言都使用這種編程范式。
使用命令式編程范式具有如下劣勢:
? 很多問題都無法按照順序執行的方法來解決。
? 缺乏引用透明性,這意味著變量的狀態可以改變,使得程序難以理解。
? 調試不簡單。
? 只能實現有限的抽象類型。
2.1.2 邏輯式編程范式
邏輯式編程范式也稱為基于規則的編程范式。它基于謂詞邏輯,是解決問題的一種聲明性方法,其側重于關系。比如Prolog就是一種邏輯式編程語言。
這樣的程序可以分為三個部分:
? 定義和聲明、定義問題的域。
? 在相關域中給定問題的事實。
? 一些表達式得出的結果。
邏輯式編程范式沒有控制語句,只有關系描述。用戶不需要了解程序的運行過程。因此,Y = f(X)等價于表達式r(X,Y),其中r代表一種關系,它定義了X和Y的關系。在基于規則的編程中,我們只需要提供事實(規則和公理),然后通過變量賦值來推測一些語句的證明。
另外,程序也可以從任意方向進行計算。例如:
? 當X已知時,可以計算Y。
? 當Y已知時,可以計算X。
這里給出一個定義關系的例子:兄弟—父親—母親—男性。
【范例2-1】關系
下面的代碼展示了一些關系。
01 male(X) // X是一個男性 02 father(F,X) // F是X的父親 03 father(F,Y) // F是Y的父親 04 mother(M,X) // M是X的母親 05 mother(M,Y) // M是Y的母親
這里定義了5種關系,它們都是r(參數)的形式。通過以上關系可以推測出brother定義了兄弟的關系。
brother(X,Y) // X是Y的兄弟
當然,邏輯式編程也有一些缺點:
? 可以以任意方式計算的函數其執行的效果不好。
? 基于規則的編程僅限于使用關系表達的域。
2.1.3 函數式編程范式
函數式編程范式源于純粹的數學意識形態:功能理論。它將所有的子程序都視為函數。函數(在數學意義上)接收參數并在計算后返回結果。結果取決于該函數的計算,而計算取決于我們為函數提供的輸入參數。
連續狀態在函數式編程范式中無效。函數的結果將會是另一個表達式的輸入,不會被保存為變量。函數式編程范式比其他范式更簡潔、更簡單,因為它遵循數學函數理論。函數是函數式編程范式中的第一類對象。函數可以被視為一種數據,假設函數將返回一個值,這允許我們將函數作為參數傳遞給另一個函數,或者從其他函數返回一個函數。
我們試著理解函數式編程范式,并將其與命令式編程范式進行比較。比如創建一個函數,將輸入數據映射到在命令式編程范式中執行n條語句時可能獲得的結果。
Stat指一個聲明,Stat_0, Stat_1, Stat_2, …,Stat_n是n+1個聲明。
現在,根據函數式編程范式,有:
F(Stat_0) = Stat_n
此函數將初始狀態映射到最終狀態。
接下來,我們將其分解為單個表達式,這將表示每條語句的結果。
F(Stat_0)= Stat_n(Stat_n-1(...(Stat_1(Stat_0))))= Stat_n
也可以寫成:
F = Stat_n 0 Stat_n-1 0 ... Stat_1
因此,可以通過為每條語句構造一個函數并以相反的順序執行它們,將程序從命令式編程范式轉換為函數式編程范式。雖然這不適用于所有情況或問題,但基本思想是相同的。
函數式編程范式的特點和優勢如下:
? 函數提供了高級抽象,從而降低了錯誤的可能性。
? 程序獨立于賦值操作,可以編寫高階函數,這使得函數式編程范式適用于并行計算。
? 與命令式編程范式不同,函數式編程范式保持引用透明性,這使它更適合于數學表達式。
? 函數式編程范式中的值是不可變的。
函數式編程范式也有如下一些缺點:
? 在某些情況下,函數式編程范式變得很復雜。比如通常在需要處理大量順序活動時,通過命令式或面向對象的編程范式可以更好地處理這些活動。
? 某些程序可能不如使用其他范式編寫的程序有效。
2.1.4 面向對象的編程范式
在面向對象(OOP)的編程范式中,對象是抽象出來的真實世界的實體,對象具有行為或方法,通過行為或方法可以對對象的狀態進行修改。面向對象的編程范式將重點放在對象上,這些對象屬于特定類,類具有對象可以使用的特定方法。由于對象是真實世界的實體,因此它們是封裝的,包含可以更改數據狀態的數據和方法。
面向對象的編程范式基于4個主要原則。
(1)封裝:限制從外部訪問內部的方法。有權訪問對象的方法只能操縱它們的狀態,可以防止外部方法更改對象的狀態以執行無效的操作。
(2)抽象:這是一種使用類在接口和功能方面定義概念邊界的方法,可以保護對象的內部屬性。
(3)繼承:允許類從現有類繼承屬性和行為,從而無須重寫它們,這也有助于保持一致性。因為如果有變化,我們只需要在一個地方進行修改即可。派生類可以添加自己的屬性和行為,為基類提供擴展功能。
(4)多態性:指的是具有相同名稱的函數方法,這意味著我們可以使用相同名稱的不同方法。
? 覆蓋:是運行時多態,其中的方法具有相同的名稱和簽名。區別在于其中一個方法在基類中,另一個方法在派生類中。通過重寫,子類可以具有該方法的特定實現。
? 重載:是編譯時多態,其中同一個類中有兩個或多個方法具有相同的名稱,但簽名不同。調用哪個方法取決于所傳入的值等。
2.1.5 開始Julia REPL編程
我們已經學會了如何啟動Julia REPL并理解了一些基本語句,Julia提供了各種選項來運行程序。如果已經配置好了環境變量,那么可以直接運行語句,而不用打開REPL。
【范例2-2】輸出Hello World
01 $ julia -e 'println("Hello World")' 02 Hello World
代碼01行調用了Julia的println函數,通過-e選項來執行代碼。后面使用“' '”(半角單引號)將需要執行的代碼包裹起來,因為按回車鍵會讓代碼執行,所以使用這種方式來執行一些簡單的代碼。代碼02行輸出了Hello World字符串。
除此之外,還可以執行循環語句。
【范例2-3】循環輸出Hello World
下面的代碼通過循環語句輸出了Hello World。
01 $ julia -e 'for i=1:5; println("Hello World"); end' 02 Hello World 03 Hello World 04 …
代碼01行同范例2-2,同樣使用了-e選項,但是在“' '”中加入了for循環語句,循環5次。由于篇幅的關系,并未給出全部代碼。其輸出結果是5行Hello World。
另外,還可以傳遞參數。
【范例2-4】傳參輸出
01 $ julia -e 'for i in ARGS; println(i); end' k2so r2d2 c3po r4 02 bb8 03 k2so 04 r2d2 05 c3po 06 r4 07 bb8
ARGS用于獲取腳本的命令行參數。代碼01行同樣使用了-e選項,在該行末尾輸入了一些參數,這些參數被ARGS所接收。代碼03~07行為輸出結果。
我們可以使用--help選項來查看Julia支持的所有選項。
01 $ julia --help 02 julia [switches] -- [programfile] [args…] 03 -v, --version 顯示版本信息 04 -h, --help 顯示幫助信息 05 -H, --home <dir> 設置'julia'可執行文件的位置 06 -e, --eval <expr> 評估<expr> 07 -E, --print <expr> 評估并顯示<expr> 08 -L, --load <file> 立即在所有處理器上加載<file> 09 -p, --procs {N|auto} 整數值N,啟動N個其他本地工作進程 10 "auto"啟動的工作進程數和本地核心啟動的相同 11 --machinefile <file> 在<file>中列出的主機上運行進程 12 -i 交互模式;運行REPL并且isinteractive()為真
在上面輸出中,只列舉了常用的一些選項。如果需要查看更多的選項,則可以像代碼01行一樣輸入julia --help命令。
- Mastering Zabbix(Second Edition)
- SoapUI Cookbook
- Java Web基礎與實例教程(第2版·微課版)
- 程序員面試算法寶典
- Instant Typeahead.js
- Windows Server 2012 Unified Remote Access Planning and Deployment
- Nginx Lua開發實戰
- 機器學習與R語言實戰
- Python圖形化編程(微課版)
- Building Wireless Sensor Networks Using Arduino
- Unity 3D/2D移動開發實戰教程
- JavaScript動態網頁編程
- Learning D
- Java從入門到精通(視頻實戰版)
- Mastering PostgreSQL 11(Second Edition)