`
saybody
  • 浏览: 907668 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

為什麼要學習函數編程?

阅读更多

文 / 蔡學鏞

面對越來越複雜的軟體開發需求,我們需要更高的抽象層。過去二十多年,我們將物件導向(Object-Oriented Programming,OOP)和元件(Components)的觀念注入大多數的主流imperative編程語言(例如BASIC、C、Pascal),採用這些技術可以降低軟體開發的複雜度(Complexity),增加再用性(Reusability),於是我們著實過了好一陣子安穩的生活。

但軟體的複雜度就像細菌的抗藥性一樣,依然在持續增加。當萬古黴素開始壓制不住金黃色葡萄球菌,物件導向漸漸讓軟體開發力不從心,我們要如何是好?

越來越複雜的專業領域知識、越來越多元的異質平台、越來越普遍的網路環境和多核心電腦…這些都會提升軟體開發的複雜度,我們再度陷入困境。忽然發現,古老的函數編程(Functional Programming,FP)可以解決這個階段的許多問題,原來FP是現代編程問題的一帖良方。這使得最近函數編程忽然又被炒熱,成為許多語言設計者的最愛。

相較於OOP是往真實世界的方向進行抽象,FP卻是往數學的方向進行抽象。FP的理論基礎是來自Lambda Calculus,而Lambda Calculus同時賦予FP簡單性和威力。當然除了Lambda Calculus之外,方便的List處理、自動記憶體管理、Meta-Programming也都是函數式編程語言常見的特性。

提到函數編程,就不能不提1958年被創造出來的LISP,因為它是函數編程的始祖。暢銷書《駭客與畫家》(Hackers and Painters)的作者Paul Graham提到,LISP是許多公司成功的秘訣,因為透過LISP,他們可以用精簡的人力,在很短的時間內,開發出威力強大的系統。Paul Graham本來很擔心,他這麼一鼓吹LISP,要是別人都因此改用LISP,自己就佔不到便宜了。不過作者最後的結論是,大多數的人不會這麼聰明,所以應該可以不必擔心。他說的沒錯,在《駭客與畫家》與《Practical Common Lisp》出版約五年後的今天,LISP語言在Tiobe的語言需求排行榜卻不升反降,眼看就要被擠出前20名了,我直呼大師預言神準。

雖然Paul Graham稱讚的對象是LISP,但等於間接稱讚到FP。儘管一般程式開發人員對於FP的重視程度依然不高,但是語言設計者卻對FP興致高昂。既有的主流語言(例如C#、VB)開始在新版本中加入FP的特色;新興的語言(例如Scala、JavaFX)同時結合FP和OOP,就連古老的FP語言(例如ML)也有了新的面貌(例如F#)。

C#為了支援LINQ,以進行更高程度的資料查詢抽象,開始加入FP的特色。目前LINQ已經利用FP進行meta-programming,未來LINQ還會利用FP進行concurrent programming,以充分利用現代多核心的運算環境。

F#是衍生自ML家族的OCaml,融合了一些C#和Haskell的概念。許多時候,F#和OCaml的程式是可以交互編譯的,也就是說,兩個語言的相容性很高。由於F#是目前.NET平台最重要的FP語言(也是微軟官方提供的語言),因此未來隨著FP漸漸受到重視,F#也會佔有一席之地。

但我認為這「一席之地」恐怕坪數不大,卻公設很多。.NET環境下,函數式編程的語言選擇,我的建議是:如果你是基於科學、工程的目的而寫程式,那麼F#會比較適合,如果你要寫的是「世俗化的系統」(例如Web、資料庫、RIA),那麼還是使用C#吧。因為既有主流語言的使用者,可以漸進地學習函數編程。過去的經驗告訴我們,C++會流行、Java會流行,某一部份的因素是因為它們是從既有的語言去做加強(C++是C的強化版、Java是C/C++的改良版)。

但是我認為使用C#中語言的人,或許會因為使用LINQ之類的技術,而「間接」用到函數編程,但是很少有人在規劃軟體時會直接使用到函數編程的重要特色。「使用函數編程語言」不等於「進行函數編程」,你可以用函數編程語言寫出不合乎函數編程理念的程式,正如同你可以用物件導向語言寫出不合乎物件導向理念的程式。

更何況C#因為加入太多語言特色,變得過度複雜,開始有C++化的趨勢,而「複雜」是和FP的「簡單」背道而馳的。因此對於初學FP的人,或許F#等「新瓶舊酒」語言會更適合用來學習FP的觀念,培養相對單純的FP體驗。

真的想學好函數編程的觀念,可能還是得從傳統的FP語言著手,會比較徹底。函數編程只是一個觀念,各個語言的作法和語法差異可能不小,例如LISP家族、ML家族(F#屬於這個家族)、Erlang這三者都是相當重要的函數編程語言,但是這三種語言的差異相當大。如果你是.NET使用者,就學F#;Java使用者就學JavaFX或Scala;其他使用者就學Common Lisp或Erlang。

Paradigm-Shift總是痛苦的,但這是生存之道。從OOP的Paradigm轉移到FP,一開始可能會有不適應的地方,但熟悉之後,你會很高興你學會了一個新的技能、新的思維,可以面對新的環境、新的挑戰。

我知道函數編程當然也不會是軟體開發一勞永逸的解決之道,未來還有更多的挑戰會出現。或許,下次編程挑戰的救星,會是邏輯編程(Logic Programming)也說不定。

分享到:
评论

相关推荐

    通达信DLL函数编程规范

    《通达信DLL函数编程规范.doc》很可能是文档形式的编程指南,其中会包含详细的函数介绍和示例代码,是学习和开发DLL插件的重要参考资料。 9. **测试与调试** 文件“TestPluginTCale”可能是一个测试插件,用于...

    函数编程入门 及原理讲解

    函数编程(Functional Programming,简称FP)是一种编程范式,它将计算机程序视为一系列数学函数的组合,避免使用可变数据和改变状态的方式。在函数编程中,函数是核心元素,它们可以被当作值一样传递,并且能够返回...

    通达信DLL函数编程(delphi).zip

    在金融领域,尤其是股票分析软件中,DLL函数编程可以为用户提供自定义的分析指标,增强软件的功能。 首先,我们来看"通达信DLL函数编程规范(Delphi).doc",这是一个详细的文档,指导开发者如何遵循通达信提供的API...

    函数式编程思维.pdf_函数式编程_函数式编程思维_

    函数式编程是一种编程范式,它强调将计算视为数学函数的评估,并避免可变状态和副作用。这种编程风格鼓励使用纯函数,即...学习和掌握函数式编程思维,不仅可以提升编程技能,还能为应对现代软件工程的挑战做好准备。

    现代C++函数编程模式

    现代C++函数编程模式是C++11及后续版本引入的一种增强编程范式的特性,它使得C++在传统的面向对象编程之外,增加了函数式编程的能力。这种编程风格强调使用不可变数据、高阶函数和惰性计算,尤其适用于处理多线程...

    HASKELL函数编程讲义

    在学习Haskell的过程中,掌握函数编程的基本概念以及Haskell的特性至关重要。以下是对压缩包内各文件内容的详细解读: 1. **2.Basictypes.ppt - 基本类型** 这一部分涵盖了Haskell中的基本数据类型,如整数(Int, ...

    一个超棒可视化学习函数式编程的游戏

    标题中的“一个超棒可视化学习函数式编程的游戏”暗示了我们即将探讨的是一款结合了教育与娱乐元素的游戏,它的目标是帮助用户通过游戏化的方式学习函数式编程。这款游戏可能使用了直观的图形界面来呈现编程概念,...

    面向函数式编程-讲解

    函数式编程是一种编程范式,它将计算视为数学函数的求值,并强调程序数据的不可变性以及避免副作用。在函数式编程中,程序由纯函数构成,这意味着一个函数如果给定相同的输入,总是会产生相同的输出,且不会对程序的...

    Scala函数式编程

    2 无副作用的函数式编程,同时也解释了为什么在scala中,val和var的区分为什么那么重要。 3 在做习题的过程中,尤其是在做类型推导的过程中,对原来oop,命令式编程向函数式编程转变有很大作用;而且简洁的语法,...

    swift4函数式编程学习

    在Swift4中,函数式编程是一种强大的编程范式,它允许开发者将程序视为一系列数据处理的函数,而不是状态的改变。这种编程风格有助于减少副作用,提高代码的可测试性和可维护性。 1. **函数作为一等公民**:在Swift...

    函数式编程中文版.pdf

    最后,对于大多数开发者来说,学习函数式编程的最终目的并不是要完全放弃传统的命令式编程,而是为了扩展自己的编程视野,掌握更多编程的工具和技巧。通过学习函数式编程,开发者能够写出更加优雅、可维护、高并发的...

    Python函数式编程

    为什么使用函数式编程呢?函数式编程有若干优势。首先,函数式风格的代码没有副作用,即函数不会改变外部状态或输出之外的任何东西。这使得函数在多次调用时总是能返回相同的结果,便于进行逻辑证明。此外,函数式...

    C函数编程技巧

    函数编程技巧是C语言学习的重要环节,尤其对于初学者,理解和掌握函数的使用能够极大地提高编程效率和代码质量。本文将探讨如何通过"函数框架编程法"来帮助初学者过渡到函数编程。 ### 函数框架编程法 1. **从main...

    函数编程题作业.rar

    4. **递归**:函数编程中经常使用递归,即将问题分解为更小的相同问题来解决。例如,文件可能包含使用递归实现的阶乘计算、斐波那契数列或其他递归算法。 5. **纯函数**:纯函数是那些给定相同的输入总是返回相同...

    Rust 和 Haskell 函数编程

    学习 Rust 和 Haskell 的函数编程可以帮助开发者理解如何编写更简洁、可读性更强的代码,提高代码的可靠性,并充分利用现代多核处理器的性能。这两种语言虽然有着各自的特点,但都体现了函数式编程的强大潜力,值得...

    Java-Java函数式编程教程

    Java函数式编程是一种编程范式,它强调使用函数作为程序的基本构建块,将计算视为函数的组合,并且尽可能避免改变状态和可变数据。在Java 8及更高版本中,函数式编程得到了官方的大力支持,引入了Lambda表达式、...

    javascript函数式编程

    JavaScript函数式编程是一种编程范式,它强调将计算视为数据处理的过程,并且重视函数作为第一类公民,即函数可以作为变量赋值、作为参数传递、作为返回值返回。这种编程风格在JavaScript中尤其常见,因为它提供了...

    JS 函数式编程指南

    函数式编程倾向于使用声明式代码,即表达“我想要什么”,而不是“如何去做”。例如,`Array.prototype.map`函数用于创建一个新数组,其元素是原数组元素经过提供的函数处理的结果,而非使用循环进行逐个操作。 4. ...

    JavaScript函数式编程.pdf

    函数式编程(Functional Programming)是一种编程范式,它将计算视为数学函数的评估,并且避免改变状态和可变数据。在JavaScript中,函数是一等公民,这意味着函数可以被赋值给变量、作为参数传递给其他函数以及...

Global site tag (gtag.js) - Google Analytics