學習哪些 Functional programming language 能夠拓寬眼界,學到和其他編程範式明顯不一樣的東西?
語言名稱和理由分別是什麼?
沒想到LOGO也是啊...這個小學二年級學的小王八,至今都有老師在中華學習機上演示滿天飛雪的映像...
推薦你可以讀一讀Matt Might的Advanced programming languages這篇文章
Matt Might在文章中列出了他最喜歡的四種語言:Haskell,Scala,SML/OCaml和Scheme,同時也包含了相關的學習資源。
去報公開課吧,課上講什麼語言就跟著學什麼語言。樓上諸位推薦的語言和書都不錯,我全都看過,和因為拖延症坑過。還是有人講/有地方討論/有題目做/有deadline逼的學習方式比較靠譜。
Programming Languages (Coursera): Coursera
Functional Programming Principles in Scala (Coursera): Coursera
Introduction to Functional Programming (edX): Introduction to Functional Programming
Paradigms of Computer Programming - Fundamentals (edX): Paradigms of Computer Programming
Paradigms of Computer Programming - Abstraction and Concurrency (edX): Paradigms of Computer Programming
這些課一開始講的都是函數式語言共享的一些概念,包括higher-order functions,closure,currying,algebraic data types/pattern matching/type inference等等。這些內容容易掌握,也是大多數函數式語言舉一反三的語義所在,在一門課上學會一遍,其他課可以跳過很多內容,上手一門函數式語言也比較快了。
不那麼舉一反三的東西包括:lazy evaluation和monad;函數式和面向對象兩種範式的內在聯繫(Programming Languages課有涉及Ruby和Standard ML對比的作業);static/dynamic typing的正確姿勢(PL課還有教Racket),等等。這些也是細心品味不同函數式語言的差異,加深理解的地方。
還有一樣課上很少講但對函數式編程很重要的東西就是函數式的數據結構。只是想用好的話,看Clojure Programming第2、3章就大概清楚怎麼回事了,想深入了解和實現的話,刷一下Purely Functional Data Structures也是極好的。。
再補充一下沒有必要看的東西:學Lisp不需要看lambda calculus,學Haskell不需要看範疇論。不要捨近求遠。scheme
語法簡單到極致
同時學習 SICP,你就會對編程有更深入的了解
推薦這個課程:
Programming Languages - Coursera.org
這裡用的主要編程語言是 ML 和 Racket ,用來交作業的。
後面還會拿它們跟 Java 和 Ruby 比較。
個人覺得,如果你要看 paper 的話,haskell 是絕對繞不過去的坎。(believe me I tried)
如果不能很好的理解 lazy 的話,讀很多論文都會很不舒服。
所以不管 haskell 設計怎麼樣,是不是有些過時了,haskell 是絕對必須要學的。
所以如果想現在開始的話,不如從 haskell 開始吧。
mathematica確實能拓寬眼界,但帶來的負面也是有的。
我是物理狗,mathematica經常用來畫圖,處理實驗數據什麼的,還用它來處理圖像。mma最大的優勢是龐大的庫,和對符號計算的支持。但是,用它來學習FP我覺得不合適。
FP類語言(scheme,SML,Haskell,OCaml)除了feature外還有什麼優點? 那就是他們是研究programming language theroy的計算機科學家們細心設計的,優雅簡潔,設計失誤較少。這對初學者來說很好,他們在一定程度上可接觸到真正的計算機科學,並不被語言的錯誤(小的來說是設計失誤)所誤導。
而mma呢,是Wolfram alpha和其團隊所設計的,
Mathematica built on the ideas in Cole and Wolfram"s earlier Symbolic Manipulation Program (wiki) ;
Symbolic Manipulation Program, usually called SMP, was a computer algebra system designed by Chris A. Cole and Stephen Wolfram at Caltech (wiki).
這說明mma的前期語法和語義設計是由wolfram和 Cole 設計的,他們和plt的專家的理論水平仍有差距(儘管wolfram是粒子物理大神,20歲就拿到了Phd學位,但是隔行如隔山,plt方面的功力一定不如plt專家們)
放結論,mma確實有一些設計不好的地方。
一、上面已有人提到了,標榜自己有functional programming特性,你好意思遞歸這麼慢。
二、List,Array 不分 ,文檔上寫著List即Array,別逗了。那你還用List這個關鍵字。天啊!後面又寫著List即Array,所以不建議表遞歸。 哎,car(First),cdr(Rest),cons你們別走啊,等等我!
三、
mma的還有一個設計我不太喜歡,就是 符號表達式(用於符號計算) 和 自己語言的表達式不分。
舉例來說:
If[a==0,x,x+x]
這個表達式中,不看上下文,你不知道a,x是variable還是符號表達式"a","x",也不知道x+x 代表 variable x的值加 variable x的值 還是 僅僅是符號表達式 "x+x" .
如果我用scheme寫,怎麼表達這兩個意思?
1.
(if (= a 0)
"x
"(+ x x))
你看,我quote了符號表達式。
2.
(if (= a 0)
x
(+ x x))
以類型來考慮,這種做法也是不合適的,符號表達式的類型是 symbol exp,而x的類型是由scope中x binding的值類型來推斷的。
那麼,對符號表達式的積分的類型和對(R-&>R)的函數積分的類型也是不同的,
分別是
integrate : symbol exp -&> symbol exp 和
integrate : (R-&>R)-&>R-&>R-&>R
什麼你說怎麼重載?這不太重要,要答案也有比如Haskell里用type class.
好了我們還有eval函數,能計算符號表達式,什麼意思呢?如下
(eval "(lambda (x) (+ x x)))
mma也應當設計成這樣的:
Eval[ Quote[Function[x+x]]]
mma和scheme都是dynamic typed language 你可以不考慮類型,考慮了eval 就麻煩了。
這不只是事關優雅,不信請考慮plot函數,
例子我忘了,回寢室翻一下mma的"教材」補上。
(這裡待補)
四、
說到教材我想起來了,mma至少國內沒什麼好教材(說錯請指出),基本上都是當作計算器再講。國外呢,好像Spinger的一套還可以(我沒看過,就看過目錄,但我還是相信Springer的),但一套這麼多本,一本這麼厚,好累啊;mma Cookbook 據說也還可以,其餘呢?
但FP領域的好教材可多了,他們能迅速地帶你了解FP,程序語言,甚至是計算的本質。
要實用,請學clojure, 運行於jvm上的函數式樣語言。
要想體會函數編程的美,學scheme,讀完SICP,編程水平以及對計算本質的認識都可以上至少兩個台階。
unlambda(http://www.madore.org/~david/programs/unlambda/)
Lisp Clojure Scheme Arc應該算是一個系列的東西了。裡面比較推薦CLojure,Scheme貌似變成了Racket了。
Haskell 純純的函數式,我的理解只有這麼多。
Erlang 沒用過
Python 一般,函數的不是很徹底。
Ruby 比大蟒蛇要好。
作為函數式腦殘粉,sicp必讀,雖然我自己也沒看完。
入門說吧 LOL就不錯。不是英雄聯盟。land of lisp。
Clojure有個徐明明的中文翻譯的版本。
Racket(Scheme)
1. 它的設計與實現都由最頂級的程序語言專家完成
2. 這些專家本身都是非常優秀的老師、教授,所以 Racket 的
- 文檔非常好
- 郵件列表非常友好
看sicp了解一下scheme打底子,然後看haskell的惰性求值等特性時不會感到玄乎
不要看範疇論, 至於 monad, y combinator 這種東西看不明白就放下, 先寫兩行代碼, 除非是學生, 沒必要在這上面花費太多時間推薦先學scheme。the little schemer 和 the seasoned schemer。
然後建議你在滿腦子都是函數式編程的觀念的時候暫停一下。因為這時候你很可能開始憤世嫉俗,覺得C系就是渣渣。建議你這時候停下來再看一遍the c programming language。重新拾起變數的力量。
然後向你推薦lua。俺學過了scheme和C以後再看lua就覺著,卧槽,這就是我要找的語言。。。
------------------------------------------------------
仔細想想的話,其實並沒學到什麼。自學果然不靠譜啊。最近看了a dicipline of programming,又開始看cpp primer,5th。又刷了會leetcode。
沒發現函數式編程那一套理論有啥好的。
我理解的函數式編程就是遞歸+能把lambda玩出花來,想幹什麼都能用lambda搞定。
可是真的有必要麼。。。
推薦MIT Scheme,我每年都重讀一遍。
讀這本書《計算機程序的構造與解釋》:計算機程序的構造和解釋(原書第2版)/艾伯森
原因:簡單的說,你會真正掌握編寫程序的精髓所在,明白用一切語言思考問題的方法本質,好比學習應用語言是學習英文,而學習MIT Scheme是學習如何組織自己的語言清晰表達自己想說的話。
詳細背景:
在網上有這樣一句有趣的評論:計算機科學的大部分,就是在重複發現很久以前別人就早已發現過的東西。當然,這是一句玩笑。不過我們可以給這句玩笑接個下巴:對於程序語言中的每一個重要概念,你都可以先在 Lisp 當中發明一次,再在 C++ 裡面發明一次,再在 Java 裡面發明一次,再在 Python 裡面發明一次,再在 Perl 裡面發明一次,再在 Ruby 裡面發明一次,當然,最後還要在 C# 裡面再發明一次。我們以此開始我們對 Scheme 的介紹。^_^
Scheme 的前身是 Lisp。和 Scheme 一樣,這也是一門誕生在 MIT 人工智慧實驗室的語言。 據說 Lisp 在程序語言的族譜上,班輩僅次於 Fortran,是第二古老的語言。但和 Fortran 不同,Fortran 經常被大名鼎鼎的計算機科學家批評,作為反面教材,這些計算機科學家當 中有著名的圖靈獎獲得者 Edsger Dijkstra。而 Lisp 和 Scheme 恰恰相反,它們常被計算 機科學家作為正面例子,一個優秀作品的例子。讚揚 Lisp 的人當中有 Smalltalk 和圖形 用戶界面的發明人之一 Alan Kay。
Lisp 由圖靈獎獲得者 John McCarthy 發明。據說一開始 McCarthy 只想把這門他正在設計 的語言的語法的設計,往後拖一拖,等到後面有趣的工作做完了,再回頭來給這門基於 Lambda 演算的程序語言加上為數學家們所熟悉的語法。可是 McCarthy 的一個學生很快發 現,直接在還沒有正式語法的抽象語法裡面寫程序,感覺非常好。就用不著一個正式的語法 了。於是 Lisp 誕生了。Lisp 重要的特徵就是:第一,基於 Lambda 演算的計算模型;第 二,加上 List processing,這也是 Lisp 名稱的由來;第三,直接在抽象語法裡面工作, 這是非常特別的。前兩個重要特徵,是 McCarthy 天才的設計,第三個特徵則是有趣的巧合。
又過了十多年,還在 MIT 人工智慧實驗室,不過這次不是 McCarthy,而是兩個更年輕的計算機科學家。Guy Steele, Jr. 和他的老師 Gerald Sussman 合作對古典 Lisp 做了兩個重 要改進。一是把 Lisp 從 Dynamic scope 變成了 Lexical scope。現在大家熟悉的幾乎所 有的語言都是 Lexical scope,所以大家見怪不怪了。後來 Steele 成為 Common Lisp 設 計的主力,Common Lisp 把 Scheme 的 Lexical scope、還有其它一些由 Scheme 所創造的 特徵,都加入到主流 Lisp 語言當中,Dynamic scope 終於成為了歷史。Steele 和 Sussman 做的另一個主要改進是把 Continuation 這個概念引入到程序語言裡面。這樣一門 新的程序語言就此誕生。他們按照人工智慧實驗室的傳統,把它命名為 Scheme。
這個 Continuation 據說是計算機科學裡面,在程序語言設計這個領域,最讓人感到激動, 並且在開始學習的時候,也是最讓人感到困惑的概念。或許有些讀者朋友聽說過 Continuation,這些讀者朋友可以嘗試分析一下下面由 David Madore 提出的著名的"陰陽 迷題"。David Madore 是有名的 Unlambda 語言的發明人。怎麼沒人推薦Mathematica呢?
Mathematica是一款應用領域相當廣泛的優秀數學軟體。沃爾夫勒姆和他的工作團隊在1986年開始Mathematica的研發。Mathematica1.0於1988年的1月23日正式發行。在2008年12月發行的Mathematica7.0已經有相應的中文版本。Mathematica8.0也已經於2010年11月和2010年12月分別推出了相應的英文版和日文版。
Mathematica程序設計語言以「條目重寫」為基礎,並支持函數式和過程式程序設計(儘管一般來說函數式程序設計更為高效)。Mathematica的一項特色是,新的代碼是以程序包(Package)的形式添加的,比如Mathematica語言中的文本文件。
2008年,O"Reilly技術學校聯合沃爾夫勒姆公司共同開發了AJAX版本的Mathematica,並用於在線數學課程
[5]
。
沃爾夫勒姆公司於2011年3月23日發布了Mathematica 8.0.1簡體中文版。該版本增加了500多個新函數,功能涵蓋更多應用領域,並擁有更友好更高質量的中文用戶界面、中文參考資料中心及數以萬計的中文互動實例,使中國用戶學習和使用Mathematica更加方便快捷。
Mathematica的功能包括:
[6]
使用一行代碼可顯示的圖形
- 各種基本數學函數庫
- 各種特殊屬性函數庫
- 矩陣和數據操縱工具,包括對稀疏矩陣的處理
- 支持複數、任意精度數、區間算術和符號運算
- 2維和3維數據以及函數的可視化和動畫工具
- 求解方程組、常微分方程、偏微分方程、微分代數方程、時滯微分方程、遞推關係式等等
- 離散和連續微積分的數值和符號工具
- 多變數統計程序庫,包括支持100多種數據分布的數據擬合、假設檢驗、概率和期望的運算
- 對運算和應用程序添加用戶界面的各種工具包
- 約束和非約束以及局部和全局的最優化技術支持
- 程序語言支持:過程式編程語言、函數式編程語言和面向對象的編程語言
- 圖像處理工具
[7]
,包括圖像識別
- 提供用於圖論中圖的分析和可視化的工具
- 分析組合問題的工具
- 用於文本挖掘的工具
- 數據挖掘的工具,比如聚類分析、字元串對齊和模式匹配
- 數論函數庫
- 金融運算的工具,包括期權、債券、年金、派生工具等的計算
- 群論函數
- 技術文本處理,包括公式編輯器和自動報告生成
- 用於聲音、圖像和數據的小波分析程序庫
- 控制系統程序庫
- 連續和離散的積分變換
- 導入和導出數據、圖像、視頻、GIS、CAD
[8]
等各種文件格式,並支持對生物醫學類數據的輸入和輸出
- 鏈接Wolfram Alpha的大量數學、科學、社會經濟學類的數據集合
- 查看並且重新使用前面的輸入和輸出(包括圖像和文本記號)的筆記本界面
- 和基於DLL、SQL、Java、.NET、C++、FORTRAN、CUDA、OpenCL以及超文本傳輸協議的系統相鏈接的工具
- 編寫並行程序的工具
- 當與互聯網連接時,在筆記本中可同時使用「自由格式語言輸入」(一個自然語言型的用戶界面)
[9]
和Mathematica語言
更多的內容去看維基百科吧:http://zh.wikipedia.org/wiki/Mathematica
如果要拓寬眼界(意思是說能學到和其他編程範式明顯不一樣的東西),那麼一定要來試試Mathematica,絕對拓寬眼界!
學到最後你會發現不過都是「規則系統」而已,然後你會去試圖構建自己的規則系統和世界
推薦 Erlang
理由:
- 純正的 functional programming
- 將 functional programming 的思想用並不反人類的語法表現出來
- 幾乎唯一一個,語言的建模涵蓋了包括網路節點在內的所有內容的系統。
外加其它所有 FP 語言的真正優點,外加 list comprehension, pattern matching, ...
基本上除了 Haskell 的 type inference 之外其它所有語言好的東西你都能找到。
一般來說現在從開拓視野的角度會推薦的主要有兩個語言:lisp和haskell
lisp我不是很熟悉,不過我知道它是函數式語言的鼻祖,應用的範圍也比較廣,被認為語言表達能力是非常強。
haskell我稍微熟悉一些,它是一個靜態類型的,純函數式,惰性的函數式語言。學習這門語言確實會有很大的視野改變,因為一進入haskell就再也沒有變數了,這會強迫你改變很多過去在命令式的習慣。這個我想從學習新范型的角度要比那些同時命令式和函數式的語言要更好,比如javascript以及python也被認為支持函數式編程,但是混合的支持能力無法達到類似haskell這樣強迫你改變思路的效果(當然實際工作中可能情況又會不一樣)
另外erlang也挺有名的,這個語言是愛立信為了通信設備而開發的,強調大量的並發和可靠性。個人理解是如果你要用於寫一個伺服器端的程序可能會非常合適。看到很多人推薦偏學院的語言,我想推薦一個實際一點的策略,我不是想說,scheme,lisp,ocamel,haskell沒用,很有用的,不過概念和範式的真正理解和掌握,是需要不斷練習,如果選擇的語言不能天天使用,學到的東西很容易片面粗淺。
所以我認為最好直接在自己每天用到的語言里去學函數式編程,事實上現代語言或多或少已經都有函數式思維的浸潤,大可以就地取材,把概念技巧運用到平時的編程任務中去。- Functional programming in C
- Functional programming in C++
- Functional Java
- Functional Programming python HOWTO
- Functional Aspects of Ruby
- Functional Programming in PHP
- A Gentle Introduction to Functional JavaScript
只是想拓展視野什麼的lambda calculus就能滿足你了,其他的你學了也用不上
我也推介lisp,當然首先這可以是一門純純的函數式編程語言。另外,從漲姿勢的角度來說,理由如下 :
1、相對於滿大街的c系語法,lisp 的語法堪稱十非分常很怪異,相對於見貫了c系語法的人們來說也很難學。這種怪異可以從語法層面上滿足題主漲姿勢的需求。(建議題主真要學的話,準備兩個腳踏板,使其分別具有輸入左右括弧的功能。)
2、lisp有五十多年的歷史了,都五十多年了還這麼堅挺,必然有其原因。並且作為很多特性的鼻祖(如垃圾回收,閉包,大概有八九個吧,我記不到了),肯定有其研究價值,可以從歷史和八卦的角度滿足題主漲姿勢的需求。
3、lisp的設計者是一位數學家,什麼力木塔演算(不好意思手機懶得折騰希臘字母了),又什麼lisp本質是數學,不是編程語言,所以才長盛不衰等等,反正這些高深的東西我是沒有掌握的,不過可以滿足題主理(bi)論(ge)方面漲姿勢的需求。上一個網址吧,
http://www.ituring.com.cn/article/details/530
4、說到lisp就不得不提他的宏,這貨號稱擁有世界上最強大的宏,強大到不僅前無古人,而且後無來者。因為lisp 有一個很無賴的全天25小時無條件持續激活被動天賦技能,就是一旦別的程序語言有了能和lisp 相媲美的宏時,該語言只能稱之為lisp 的方言。
如此吊炸的特性肯定不是我的水平能說得清的,我可以舉一些具體的例子來說明其強大之處:
比如早些時候java 並沒有foreach 語法,然後廣大java 程序員只能期待java的的下一版加入這個新特性,而如果是lisp 程序員眼紅這個特性的話,完全可以自己定義一個宏來實現。即使渣渣如我,也可以在五分鐘內完搞定,類似的例子很多,然後你就會覺得這門語言簡直就是龍珠裡面的萬能膠囊;
再比如,lisp 當初是根正苗紅的函數式編程語言,當面向對象興起的時候怎麼辦?lisp要被拍死在沙灘上了嘛?!?!這種事情當然還是要問問宏同不同意啦,事實是lisper通過宏很快就為其加上了面向對象的特性。當然,lisp不和別人不一樣怎麼對得起他的括弧!!所以他的面向對象還是很怪異,不是基於類(java c++),也不是基於原型(js),而是基於廣義方法(廣義方法不知翻譯的對不對)。反正從c++,java入門面向對象的我看了lisp的廣義方法後,確實感覺漲了很多好多姿勢,多到我到現在也hold不住廣義函數那一整套東西。而且最近面向切面貌似有點火,我發現廣義方法很原生的就支持了這一在spring中聽起來很高大上,寫起來複雜的特性(複雜只是相對lisp 而言,ssh 還是挺有意思的)。
基於其強大的宏,又有了諸如元編程,面向鄰域編程,會寫程序的程序等概念,完全可以滿足題主在編程思想上漲姿勢的需求。
另外,lisp 的宏真的非常的燒腦子,我自認秒算一百以內加減乘除毫無壓力,但是複雜點的宏別說寫了,就算是看我也看不懂。
不過複雜歸複雜,lisp的宏確實很吊,某歪國大牛(一向很難記住歪國人名字)說過,就算工作中永遠用不到,一個優秀的程序員也應該學lisp。
雖然想再多(zhan)介(shi)紹(zi)介(ji)紹(bi)宏(ge),無奈水平有限,再上個網址吧, http://m.csdn.net/article/2012-11-22/2812113-The-Nature-Of-Lisp
4、 最後,lisp最吊的特性就是他獨有的結尾加密技術,代碼層次越豐富,加密程度越高。據說俄羅斯某特工去美國國家航天局偷得得一份lisp代碼,但是只有最後一頁,結果傾盡一國之力也沒能從最後一頁得到任何信息。這個特性,額,應該可以滿足題主在冷笑話方面漲姿勢的需求。
額,還有一點要說明的是,我確實有點中了黑客與畫家以及各種lisp軟文的毒,所以覺得lisp很厲害,我也會繼續學習,一探究竟。但是lisp自古以來就爭議很大,狂熱者將其當作信仰,也有一大部分人覺得這是一門醜陋過時的語言。這門語言到底牛逼還是過時我也不敢打包票,因為我自己本身學的不深,而且對其認識大部分都是別人的看法。所以希望大家不要因為我的答案對lisp產生偏見,無論是偏好還是偏壞。但是我覺得從漲姿勢的角度來看,學習下還是值得的。以上。
推薦閱讀: