Python函数式编程

函数式编程

如果程序中的函数仅接受输入并产生输出,即输出只依赖于输入,内部数据不可变,避免保存程序状态,用同样的输入值反复调用可以得到相同的结果,那么这种编程范式就称为函数式编程(Functional Programming,简称FP,又称泛函编程)

这种风格也称声明式编程(Declarative Programming),与之相对的是指令式编程(Imperative Programming),后者中的对象会不断修改自身状态。函数式编程强调程序的执行结果比执行过程更重要,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程。

函数编程语言最重要的基础是λ演算(lambda calculus),函数可以像数值一样被赋值于变量,还可以作为其他函数的输入(引数)和输出(传出值)进行传递。

函数式编程历史悠久,最古老的例子莫过于1958年被创造出来的LISP了。而随着程序结构复杂,面向对象编程大行其道。近年来,简洁而且特别适合计算任务的函数式编程又重新崛起,不仅仅是纯粹的函数式语言如Haskell、Clojure、Elixir等,各种流行语言javascripts、python、Objective-C、C#、Swift甚至Java都纷纷吸收函数式编程的部分形式。而且,不仅仅是计算任务,近年还出现了用FP编写的UI应用程序,如LightTable等。

Paul Graham在《黑客与画家》一书中写道:同样功能的程序,极端情况下,Lisp代码的长度可能是C代码的二十分之一。

本文作者@申导 主要采用Python语言为例,是因为它虽然不是纯粹的FP,但Python能够胜任各种编程形式,简洁优雅,通俗易懂,语法接近于Java/C++,特别适合从主流语言转过来的学习者。

继续阅读 More

Apple最新Swift编程语言之闭包

Swift作为苹果为开发者最新发布的编程语言,受到热烈的追捧。与2014世界杯同热。

作为一门动态语言,吸收了大量Python语言的特性和语法(我喜欢Python),当然也有些ruby、js和C#的痕迹,同时保持了对原objective-C库的兼容。

iBook推出了教程,中文翻译也完成了。

大家需要下载最新xcode,里面有交互式的playground可以用来学习swift。为了获得最好的体验,在 Xcode 当中使用代码预览功能。代码预览功能可以让你编辑代码并实时看到运行结果。 打开Playground

你需要知道Swift语言闭包函数 ()->()

定义一个函数

你可以用func关键字来定义函数。函数可以接收和返回0个、1个或多个参数(tuples列表)。返回类型在->符号后面。

1
2
3
func jediGreet(name: String, ability: String) -> (farewell: String, mayTheForceBeWithYou: String) {
return ("Good bye, \(name).", " May the \(ability) be with you.")
}

调用函数

1
2
3
4
let retValue = jediGreet("old friend", "Force")
println(retValue)
println(retValue.farewell)
println(retValue.mayTheForceBeWithYou)

函数类型

1
func sum(x: Int, y: Int) -> (result: Int) { return x + y }

上述函数的函数类型为 (Int, Int) -> (Int)
函数类型可以用于嵌套函数的参数类型或者返回类型。

传递和返回函数

下列函数将另一个函数作为结果返回,可以用于赋值给变量及调用。

1
2
3
4
5
6
7
8
func jediTrainer () -> ((String, Int) -> String) {
func train(name: String, times: Int) -> (String) {
return "\(name) has been trained in the Force \(times) times"
}
return train
}
let train = jediTrainer()
train("Obi Wan", 3)

可变入参函数

可变入参函数带有可变数量的入参(表示为参数类型后的...),其内容可作为数组来访问。

1
2
3
4
5
6
func jediBladeColor (colors: String...) -> () {
for color in colors {
println("\(color)")
}
}
jediBladeColor("red","green")

定义一个闭包

闭包被置于花括号{}中,且定义为()->()类型的函数。其中->分隔了入参与返回类型,其后的in关键字分隔了闭包头与闭包体。

1
2
3
{ (params) -> returnType in
statements
}

一个例子,map函数应用于数组。

1
2
3
4
5
let padawans = ["Knox", "Avitla", "Mennaus"]
padawans.map({
(padawan: String) -> String in
"\(padawan) has been trained!"
})

类型已知的闭包

当闭包的入参类型已知时,可以这样写:

1
2
3
4
5
6
7
func applyMutliplication(value: Int, multFunction: Int -> Int) -> Int {
return multFunction(value)
}

applyMutliplication(2, {value in
value * 3
})

闭包省略入参名

闭包入参可以不用参数名而是位置($0,$1,…)来访问

1
applyMutliplication(2, {$0 * 3})

甚至,如果闭包是函数的最后一个入参时,圆括号可以这样省略掉

1
applyMutliplication(2) {$0 * 3}

(翻译自 http://fuckingswiftblocksyntax.com/