如何寫出易讀的 Mathematica 代碼?

命令式範式語言,比如C python matlab,一般一行比較短,通過縮進,比較易讀。

而mathematica作為函數式範式為主的語言,代碼通常是函數嵌套函數,一行通常很長,那麼如何寫出易讀的mathematica代碼?能否給一些建議,謝謝。


善用//,/@,@等語法糖。。

先佔坑。。

=========================

(*實驗室都去唱K了就我還在這邊等老闆來實驗室,不開心,先隨便寫點。。*)

1,首先,能用Mma格式化表達算是就盡量用。。為什麼增加可讀性我就不說了。。你總不能告訴我下面兩個表達式的兩種寫法你喜歡看第一個吧

當然這些表達式不僅僅是除法,指數,開方之類的,還包含矩陣,積分,偏微分,Σ,連乘符,分段函數,圖的節點連接甚至乃到希臘字母等等,就不再舉栗子了,反正你知道我在講什麼。。

2,之前隨口說的那些語法糖,比如說:

ToString[Total[Take[Select[Range[1000], PrimeQ], 3]]]

一瞬間你知道它在幹什麼嗎?【我還是隨手舉例子,沒經大腦】

但是換一種寫法:

Range[1000]~Select~PrimeQ~Take~3 // Total // ToString

跟我讀,從Range[1000]裡面Select出PrimeQ來,Take出3個,Total一下,在ToString一下

當然這種東西怎麼運用還是看你經驗了,不明所以為了展示技巧而混用簡直作死,一般情況下單個參數用Fun@par,最後以某種形式展現或者不是很核心的計算得採用//,比如xxForm一類,或者計算運行時間的那些。。

也不展開講了。。自己體會

3,當使用lambda但是函數中有對矩陣索引的時候往往會變得很難看,栗子:

主要就是[[i]]這種表達式。。說句題外話,最好配置mma成按ctrl+[就可以直接輸入[[的格式化形式,ctrl+]就可以輸入]],而不是每次都是esc+[+[+esc,esc+]+]+esc。。。不想這麼輸就別提式子有多醜了,一個中括弧就夠了,還兩個。。

這種時候要善用mma的替換/.,效率我不清楚,至少可讀性會好一些吧。。

4,原則上Mma不是那種適合for語句的語言,但是有時必須要for,但是你知道的,for的參數四個,參數一多就不好看,一般可以參照C++的格式,舉個例子你就知道了:

變成:

5,匿名函數不要一個套一個再套一個。。栗子再說,有事,先撤。。


我猜會來問這個問題的,大都是剛剛入門一點Mathematica吧,那麼你估計也不會寫長,特別長或者特別特別長的代碼。

對於短代碼,肯定是一層一層嵌套的,大概三四層吧,然後每一層完成一個任務,大概是這樣子。那麼一兩層你覺得邏輯大概到那裡了,前後就都打兩個換行。這樣一層的邏輯結構就清楚了。

對於中形代碼,注意一定要用好函數式的結構,實現一個功能,你覺得大概需要五行了,就不妨單開出來寫個函數,然後最後一級一級嵌套。然後函數名命名的好點,函數定義的時候模式寫清楚,自然也就okay了。

假如我不幸猜錯了,那麼其實只要記得善用Mathematica那麼好的排版工具,Alt+1~7,寫清楚章節,所有那種羅列n種操作的函數定義盡量統一,輸出盡量統一,這樣寫起來邏輯順溜,調試啊,看啊也自然都方便。


Mathematica只是個調試器,大規模編程最好換個IDE...

可讀性高的代碼在我看來有三個特點:

整體上函數式風格,實現上過程式思維,細節處函數式編程

舉例解釋.

工程上使用Mathematica的是高度密集的磚塊式代碼...

很有重金屬風格...很True Man,放張圖感受下:

Easy難度:

整體上函數式風格.

函數式風格就是------工欲善其事,必先利其器!

幹活先寫個函數而不是直接開干,先把每一步封裝成函數.然後一群函數複合起來直接搞定!

實現上過程式思維:

函數具體的實現都按過程式思維來好了,Mathematica是多範式混合編程語言,不比拘泥於函數式.

每一步都給個名字,然後一行只干一件事,干不完換行的話縮進加一級.

If這種寫一行,判斷條件很煩抽出來給個名字,我最討厭一個If換三行...

循環按這個規則會變長條形...所以我不太喜歡循環...

知道自己每行在幹嘛,以行為單位理解.

細節處函數式編程:

多用匿名表達式,多用各種語法糖/@,@@,@@@,#的意思至少要懂.

表操作思想,整體操作思想,不要死扣一個個列表元素...

千萬不要用For循環...Fold,Nest,Do哪個都比For好上萬倍啊...

Normal難度:

如果你的函數超級複雜,記得單獨開一個環境,避免變數污染...

代碼最好不要超過一屏,就是右邊這條線,一件事要這麼長的邏輯本來就不大對勁...

然後寫好報錯,做好調試工作,多寫點注釋

最後寫個說明,最好附上例子,免得自己也忘了這個函數幹嘛的...

一般是每類子輸入都寫一個子函數

比如吃進String寫個foostr,吃進列表foolist

然後最後的函數直接Switch不同的類型就行了...

最好理解DownValues這種概念,不過不建議用下值,還是子函數好...

說Mathematica沒法調試的...大概是連debug模式都沒聽說過...

Hard模式:

清楚文件結構,一類代碼放一起,還有多語言編程也不錯

Mathematica的快速編程能力是所有語言中最強的,就是運行速度有時有點問題

尤其是不得不寫循環或者用編譯的情形

這種情況下可以用C,C++,C#,Java等寫好然後直接調用...圖中就使用了混合編程.

最後代碼寫進初始化文件init.m 自己以後用的時候直接看ussage大概就知道幹嘛的,省的再去理解一遍.Hell難度:

模式匹配...千變萬化...學無止境...

反正封裝成函數了,知道輸入和輸出就行了,不用去理解...

此代碼為Mr.Wizard著名的7行秒梭哈

可以去Euler Project看看別的語言要多少行


對齊縮進添注釋。


推薦閱讀:

怎樣用Mathematica解帶字母的方程組?
編寫過10萬行Mathematica代碼 (精簡後) 是種什麼樣的體驗?

TAG:WolframMathematica | 代碼風格 |