lambda/closure – javascript、python、scala 到 java se 7

52
lambda/closure JavaScriptPythonScala Java SE 7 林信良 http://openhome.cc [email protected]

Upload: justin-lin

Post on 03-Jul-2015

1.276 views

Category:

Technology


2 download

DESCRIPTION

2010 Java Certification Day 你可以在以下鏈結找到中文內容: http://www.codedata.com.tw/java/understanding-lambda-closure-1-from-javascript-function-1/

TRANSCRIPT

Page 1: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

lambda/closure – JavaScript、Python、Scala 到 Java SE 7

林信良

http://openhome.cc

[email protected]

Page 2: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

以下純屬

Page 3: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

Update to date

• JDK 7 Features updated ! Plan B

has apparently been approved

– http://www.baptiste-wicht.com/2010/09/jdk-7-features-updated-plan-b-is-apparently-here/

• 2011 Java SE 7 沒有 Closure … Orz

• 2012 Java SE 8 才有 Closure ... XD

• 2012 世界末日才有 Closure … 囧rz

Page 4: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

議程 • lambda

• closure

• 動靜之間

• 沒有 lambda/closure 的 Java

• Java SE 7 lambda/closure 提案

Page 5: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

/lambda/

What is

http://en.wikipedia.org/wiki/Lambda

In programming languages such as

Lisp and Python, lambda is an

operator used to denote

anonymous functions or closures

Page 6: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

從 Java…呃!JavaScript 來認識起…

Page 7: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

function doSome(param) {

// 作些事

}

var doSome = function(param) {

// 作些事

};

function(param) {

// 作些事

};

function(param) {

// 作些事

};

* Function literal

* Function 實例

* new Function('param', '函式本體');

* Anonymous function

Page 8: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

既然函式是物件,那麼可以作什麼?

• 指定給別的變數

• 這跟樓下的是一樣的 …

function foo(arg) {

document.write(arg , '<br>');

}

var zzz = foo;

zzz('demo');

var foo = function(arg) {

document.write(arg , '<br>');

};

var zzz = foo;

zzz('demo');

Page 9: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

既然可以指定給別的變數,就可以…

• 作為引數傳入函式中

• 這跟樓下的是一樣的 …

function show(element) {

document.write(element + '<br>');

}

[1, 2, 3, 4, 5].forEach(show);

var show = function(element) {

document.write(element + '<br>');

};

[1, 2, 3, 4, 5].forEach(show);

Page 10: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

文化 與

風格

Page 11: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

走訪陣列

var array = [1, 2, 3, 4, 5];

for(var i = 0; i < array.length; i++) {

doucment.write(array[i] + '<br>');

}

[1, 2, 3, 4, 5].forEach( function(element) {

doucment.write(element + '<br>');

} );

Page 12: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

可作為引數傳入函式?那就可以設計 callback 函式..

• 實作 forEach

Array.prototype.forEach = function(callback) {

for(var i = 0; i < this.length; i++) {

callback(this[i]);

}

};

[1, 2, 3, 4, 5].forEach( function(element) {

doucment.write(element + '<br>');

} );

Page 13: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

當函式是物件時

• 可以根據需要傳遞給另一個名稱參考

• 不再被動呼叫,可主動指導別的函式動作

• 流程中不同演算,設計callback函式代換

簡化的語法

不同的設計

Page 14: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

closure?

What is

Page 15: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

Closure

• 文言文….

–函式物件建立時,自由變數(Free variable

)綁定了當時作用範圍中的變數,使被綁定的變數之作用範圍跟隨著被建立的函式物件

• 白話文 就是….

Page 16: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

r2

心愛的跟別人跑了…XD

Page 17: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

網頁資源載入完成後執行一次

這是一個區域變數

function init() {

var local = 10;

setInterval(

function() {

alert(new Date() + ': ' + local);

local++;

},

3000);

}

window.onload = init;

function() {

alert(new Date() + ': ' + local);

local++;

}, 自由變數(Free variable)

Page 18: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

• local這樣的變數對函式實字部份的宣告來說,稱為自由變數(Free variable)

• 自由變數真正的意義,必須結合函式實字以外的環境才可以得知

Page 19: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

你說過要跟我海枯石爛啊啊啊啊…

init 函式…

r2

Page 20: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

實際的應用呢?…

• 在 JavaScript 中模擬私用性…

function Account(money) {

var balance = money;

this.getBalance = function() {

return balance;

};

this.deposit = function(money) {

if(money > 0) {

balance += money;

}

};

}

var account = new Account(1000);

account.deposit(500);

account.balance = 1000;

Page 21: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

var account = new Account(1000);

var account = {};

Account.call(account, 1000); function Account(money) {

var balance = money;

this.getBalance = function() {

return balance;

};

this.deposit = function(money) {

if(money > 0) {

balance += money;

}

};

}

* 函式是物件 * 物件可以擁有方法

Closure 綁定的是自由變數本身,而不是其值!

Page 22: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

正確的說法叫腳踏兩(多)條船…XD

Page 23: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

環環相扣

Page 24: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

def max(m, n):

return m if m > n else n

print(max(10, 3)) # 顯示 10

maximum = max

print(maximum(10, 3)) # 顯示 10

max = lambda m, n: m if m > n else n

print(max(10, 3)) # 顯示 10

My name is Python ….

Page 25: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

function max(m, n) {

if(m > n) {

return m;

}

return n;

}

def max(m, n):

return m if m > n else n

function(m, n) {

if(m > n) {

return m;

}

return n;

};

lambda m, n: m if m > n else n

函式定義

匿名函式

Page 26: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

從函式傳回函式 import math

def prepare_factor(max):

# 一些建立質數表的過程,需要一些時間與資源

primes = [i for i in range(2, max) if prime[i] == 1] # 質數表

def factor(num):

# 利用質數表進行因式分解的過程

while primes[i] ** 2 <= num:

if num % primes[i] == 0:

list.append(primes[i])

num //= primes[i]

else:

i += 1

return factor # 傳回函式

factor = prepare_factor(1000)

print(factor(100)) # 顯示 [2, 2, 5, 5]

Closure

Page 27: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

當函式是物件時

• 可以根據需要傳遞給另一個名稱參考

• 不再被動呼叫,可主動指導別的函式動作

• 流程中不同演算,設計callback函式代換

• 可以形成 Closure 綁定自由變數(資源)

• 可以從函式中傳回函式

Page 28: lambda/closure – JavaScript、Python、Scala 到 Java SE 7
Page 29: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

Python 只作「半套」?。。XD

18 1

Page 30: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

• 變數無需宣告就可以直接使用並指定值

• 除非特別使用global或nonlocal指明(Python 3),否則變數範圍(Scope)總在指定值時建立

Page 31: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

def func():

x = 10

def getX():

return x

def setX(n):

x = n

return (getX, setX)

getX, setX = func()

getX() # 10

setX(20)

getX() # 10

def func():

x = 10

def getX():

return x

def setX(n):

nonlocal x = n

return (getX, setX)

getX, setX = func()

getX() # 10

setX(20)

getX() # 20

Page 32: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

def max(m: Int, n: Int): Int = {

if (m > n)

m

else

n

}

val max: (Int, Int) => Int = (m: Int, n: Int) => if(m > n) m else n

函式定義

匿名函式

Page 33: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

def max(m: Int, n: Int): Int = {

if (m > n)

m

else

n

}

val max: (Int, Int) => Int = (m: Int, n: Int) => if(m > n) m else n

函式定義

匿名函式

Page 34: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

動態定型語言 • 型態資訊是在資料本身而不是變數

• 變數本身的型態是在執行時期運算得知,也同一變數可以參考至各種型態的資料。

function max(m, n) { if(m > n) {

return m;

}

return n;

}

def max(m, n):

return m if m > n else n

function(m, n) {

if(m > n) {

return m;

}

return n;

};

max2 = lambda m, n: m if m > n else n

Page 35: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

靜態定型語言

• 根據資料的型態資訊,將變數及運算式進行分類,型態資訊是在宣告的變數上

• 在執行時期變數的型態資訊無法改變,資料只能被指定至同一種型態的變數

def max(m: Int, n: Int): Int = {

if (m > n)

m

else

n

}

val max: (Int, Int) => Int = (m: Int, n: Int) => if(m > n) m else n

語法上的冗長

Page 36: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

如果要設計callback函式…

def selection(number: Array[Int], order: (Int, Int) => Boolean) {

...

val o = order(a, b)

}

val arr = Array(2, 5, 1, 7, 8)

selection(arr, (a: Int, b: Int) => a > b)

val arr = Array(2, 5, 1, 7, 8)

selection(arr, (a, b) => a > b)

val arr = Array(2, 5, 1, 7, 8)

selection(arr, (_: Int) > (_: Int))

val arr = Array(2, 5, 1, 7, 8)

selection(arr, _ > _)

類型推斷 type inference

Page 37: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

終於輪到我登場了嗎?。。XD

Page 38: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

目前 Java 沒有 lambda/closure

List<String> list = new ArrayList<String>();

list.add("Justin");

...

Collections.sort(list, new Comparator<String>() {

public int compare(String s1, String s2) {

return -s1.compareTo(s2);

}

});

假設 Java 有 lambda/closure

Collections.sort(list, (s1, s2) => -s1.compareTo(s2));

借一下 Scala 的語法

Page 39: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

目前 Java 沒有 lambda/closure

• 所以無法設計 callback 函式

• 目前由 callback 物件來實現

語法上的冗長

也不僅是語法上的冗長

Page 40: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

public void doSome() {

final int res = 10;

ISome o = new ISome() {

public void doIt() {

int result = res * 10;

….

}

}

}

編譯器強迫你要加上 final

表面上…你綁定了res

事實上...編譯器只是建立一個區域變數res

把外部res指定

給區域變數res

所以編譯器強迫你要加上 final

Page 41: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

就像 Python 只作「半套」?。。XD

18 1

Page 42: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

Lambdas in Java Preview

• http://stronglytypedblog.blogspot.com/2010/06/lambdas-in-java-preview-part-1-basics.html

• http://stronglytypedblog.blogspot.com/2010/07/lambdas-in-java-preview-part-2.html

• http://stronglytypedblog.blogspot.com/2010/07/lambdas-in-java-preview-part-3.html

• http://stronglytypedblog.blogspot.com/2010/07/lambdas-in-java-preview-part-4-proposal.html

• http://stronglytypedblog.blogspot.com/2010/07/lambdas-in-java-preview-part-5-apache.html

Page 43: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

int doubler(int x) {

return 2 * x;

}

...

doubler(3);

#int(int, int) sum = #(int x, int y)(x+y);

int sum(int x, int y) {

return x + y;

}

#int(int) doubler = #(int x)(2*x);

doubler.(3)

Page 44: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

max = lambda m, n: m if m > n else n

max(10, 3)

val max: (Int, Int) => Int = (m, n) => if(m > n) m else n

max(10, 3);

#int(int, int) max = #(int x, int y) {

if (x >= y) return x;

else return y;

};

max.(10, 3);

Python

Scala

Java

Page 45: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

void selection(int[] array, #boolean(int, int) order) {

...

boolean o = order.(a, b);

}

selection(arr, #(int a, int b)(a > b));

def selection(number: Array[Int], order: (Int, Int) => Boolean) {

...

val o = order(a, b)

}

selection(arr, (a, b) => a > b)

Scala

Java

Page 46: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

目前 Java 沒有 lambda/closure

List<String> list = new ArrayList<String>();

list.add("Justin");

...

Collections.sort(list, new Comparator<String>() {

public int compare(String s1, String s2) {

return -s1.compareTo(s2);

}

});

假設 Java 有 lambda/closure

Collections.sort(list,

#(String s1, String s2)(-s1.compareTo(s2)));

Page 47: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

##int(int)(int) sum = #(int x)(#(int y)(x+y)); ##int(int)(int) sum = #(int x)(#(int y)(x+y));

傳回函式 #int(int)

Page 49: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

void selection(int[] array, #boolean(int, int) order) {

...

boolean o = order.(a, b);

}

selection(arr, #(int a, int b)(a > b));

void selection(int[] array, Order order) {

...

boolean o = order.compare(a, b);

}

selection(arr, (a, b) -> {a > b});

public interface Order {

public boolean compare(int a, int b);

}

Function type

SAM(Single Abstract Method) type

More type inferencing

Scala-like syntax

Page 50: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

Much Better!!

val arr = Array(10, 20, 30)

var sum = 0

arr.foreach(i => sum += i)

println(sum)

int[] = {10, 20, 30};

int sum = 0;

arr.foreach(i -> { sum += i });

System.out.println(sum);

Page 51: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

我們需要?

• Lambda/Closure

• 類型推斷

• 單一抽象方法形態(SAM types)

• 可利用現存的 API

• 更多程式設計風格

Page 52: lambda/closure – JavaScript、Python、Scala 到 Java SE 7

林信良

http://openhome.cc

[email protected]