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

Justin Lin
Justin LinTechnology / Community Evangelist at Free lancer
lambda/closure –
  JavaScript、Python、Scala 到 Java SE 7
                                         林信良
                             http://openhome.cc
                        caterpillar@openhome.cc
以下純屬
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
議程
•   lambda
•   closure
•   動靜之間
•   沒有 lambda/closure 的 Java
•   Java SE 7 lambda/closure 提案
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




/lambda/
從 Java…呃!JavaScript 來認識起…
function doSome(param) {
    // 作些事
}

var doSome = function(param) {
   // 作些事
};


function(param) {   *   Function literal
   // 作些事           *   Function 實例
};                  *   new Function('param', '函式本體');
                    *   Anonymous function
既然函式是物件,那麼可以作什麼?

• 指定給別的變數
 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');
既然可以指定給別的變數,就可以…

• 作為引數傳入函式中
 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);
文化
與




風格
走訪陣列
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>');
} );
可作為引數傳入函式?那就可以設計 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>');
} );
當函式是物件時
• 可以根據需要傳遞給另一個名稱參考
• 不再被動呼叫,可主動指導別的函式動作
• 流程中不同演算,設計callback函式代換

簡化的語法
   不同的設計
What is




closure?
Closure
• 文言文….
 – 函式物件建立時,自由變數(Free variable
   )綁定了當時作用範圍中的變數,使被綁定的
   變數之作用範圍跟隨著被建立的函式物件
• 白話文 就是….
心愛的跟別人跑了…XD




     r2
這是一個區域變數

function init() {
    var local = 10;
       setInterval(
           function() {
                  alert(new Date() + ': ' + local);
                  local++;
           },                自由變數(Free variable)
       3000);
}
window.onload = init;

      網頁資源載入完成後執行一次
• local這樣的變數對函式實字部份的宣告
  來說,稱為自由變數(Free variable)
• 自由變數真正的意義,必須結合函式實字
  以外的環境才可以得知
你說過要跟我海枯石爛啊啊啊啊…

init 函式…




                r2
實際的應用呢?…
• 在 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;
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 綁定的是自由變數本身,而不是其值!
正確的說法叫腳踏兩(多)條船…XD
環環相扣
My name is Python ….

                       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
函式定義
function max(m, n) {   def max(m, n):
    if(m > n) {            return m if m > n else n
        return m;
    }
    return n;
}

                       匿名函式
function(m, n) {       lambda m, n: m if m > n else n
    if(m > n) {
        return m;
    }
    return n;
};
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:
Closure        list.append(primes[i])
               num //= primes[i]
           else:
               i += 1

   return factor # 傳回函式

factor = prepare_factor(1000)
print(factor(100)) # 顯示 [2, 2, 5, 5]
當函式是物件時
•   可以根據需要傳遞給另一個名稱參考
•   不再被動呼叫,可主動指導別的函式動作
•   流程中不同演算,設計callback函式代換
•   可以形成 Closure 綁定自由變數(資源)
•   可以從函式中傳回函式
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
Python 只作「半套」?。。XD




     1
     18
• 變數無需宣告就可以直接使用並指定值
• 除非特別使用global或nonlocal指明(
  Python 3),否則變數範圍(Scope)
  總在指定值時建立
def func():              def func():
   x = 10                   x = 10
   def getX():              def getX():
       return x                 return x
   def setX(n):             def setX(n):
       x = n                    nonlocal x = n
   return (getX, setX)      return (getX, setX)

getX, setX = func()      getX, setX = func()
getX() # 10              getX() # 10

setX(20)                 setX(20)
getX() # 10              getX() # 20
函式定義
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
函式定義
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
動態定型語言
• 型態資訊是在資料本身而不是變數
• 變數本身的型態是在執行時期運算得知,
  也同一變數可以參考至各種型態的資料。
function max(m, n) {   def max(m, n):
    if(m > n) {            return m if m > n else n
        return m;
    }
    return n;
}

function(m, n) {       max2 = lambda m, n: m if m > n else n
    if(m > n) {
        return m;
    }
    return n;
};
靜態定型語言
 • 根據資料的型態資訊,將變數及運算式進
   行分類,型態資訊是在宣告的變數上
 • 在執行時期變數的型態資訊無法改變,資
   料只能被指定至同一種型態的變數
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
如果要設計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))
                                        type inference
val arr = Array(2, 5, 1, 7, 8)
selection(arr, _ > _)
終於輪到我登場了嗎?。。XD
目前 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 的語法
目前 Java 沒有 lambda/closure
• 所以無法設計 callback 函式
• 目前由 callback 物件來實現


語法上的冗長
  也不僅是語法上的冗長
編譯器強迫你要加上 final
                                      把外部res指定
public void doSome() {
    final int res = 10;
    ISome o = new ISome() {
          public void doIt() {
                                      給區域變數res
             int result = res * 10;
            ….
        }
    }
}
     表面上…你綁定了res
     事實上...編譯器只是建立一個區域變數res

      所以編譯器強迫你要加上 final
就像 Python 只作「半套」?。。XD




      1
      18
Lambdas in Java Preview
• http://stronglytypedblog.blogspot.com/2010/06/lam
  bdas-in-java-preview-part-1-basics.html
• http://stronglytypedblog.blogspot.com/2010/07/lam
  bdas-in-java-preview-part-2.html
• http://stronglytypedblog.blogspot.com/2010/07/lam
  bdas-in-java-preview-part-3.html
• http://stronglytypedblog.blogspot.com/2010/07/lam
  bdas-in-java-preview-part-4-proposal.html
• http://stronglytypedblog.blogspot.com/2010/07/lam
  bdas-in-java-preview-part-5-apache.html
#int(int) doubler = #(int x)(2*x);
doubler.(3)

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;
}
Python
max = lambda m, n: m if m > n else n
max(10, 3)


Scala
val max: (Int, Int) => Int = (m, n) => if(m > n) m else n
max(10, 3);



Java
#int(int, int) max = #(int x, int y) {
    if (x >= y) return x;
    else return y;
};
max.(10, 3);
Scala
def selection(number: Array[Int], order: (Int, Int) => Boolean) {
    ...
    val o = order(a, b)
    …
}
…
selection(arr, (a, b) => a > b)

 Java
 void selection(int[] array, #boolean(int, int) order) {
     ...
     boolean o = order.(a, b);
     …
 }
 …
 selection(arr, #(int a, int b)(a > b));
目前 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)));
##int(int)(int) sum = #(int x)(#(int y)(x+y));

              傳回函式 #int(int)
新的提案
• http://cr.openjdk.java.net/~briangoetz/lamb
  da/lambda-state-2.html
  – No more function types
  – More type inferencing
  – Scala-like syntax
void selection(int[] array, #boolean(int, int) order) {
    ...
    boolean o = order.(a, b);
    …                                  Function type
}
…
selection(arr, #(int a, int b)(a > b));

public interface Order {
    public boolean compare(int a, int b);
}
void selection(int[] array, Order order) {
    ...
    boolean o = order.compare(a, b);
    …
}                SAM(Single Abstract Method) type
…
selection(arr, (a, b) -> {a > b}); More type inferencing

            Scala-like syntax
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);


      Much Better!!
我們需要?
•   Lambda/Closure
•   類型推斷
•   單一抽象方法形態(SAM types)
•   可利用現存的 API
•   更多程式設計風格
林信良
http://openhome.cc
caterpillar@openhome.cc
1 of 52

Recommended

Java 開發者的函數式程式設計 by
Java 開發者的函數式程式設計Java 開發者的函數式程式設計
Java 開發者的函數式程式設計Justin Lin
2.5K views58 slides
千呼萬喚始出來的 Java SE 7 by
千呼萬喚始出來的 Java SE 7千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7Justin Lin
1.9K views103 slides
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫 by
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫Justin Lin
11K views59 slides
深入淺出 Web 容器 - Tomcat 原始碼分析 by
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析Justin Lin
3.8K views52 slides
Ecmascript by
EcmascriptEcmascript
Ecmascriptjay li
7.5K views53 slides
Ecma script edition5-小试 by
Ecma script edition5-小试Ecma script edition5-小试
Ecma script edition5-小试lydiafly
780 views43 slides

More Related Content

What's hot

Java8 lambda by
Java8 lambdaJava8 lambda
Java8 lambdakoji lin
5.3K views103 slides
潜力无限的编程语言Javascript by
潜力无限的编程语言Javascript潜力无限的编程语言Javascript
潜力无限的编程语言Javascriptjay li
9.4K views127 slides
Introduction to Basic Haskell Components (In Chinese) by
Introduction to Basic Haskell Components (In Chinese)Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)ChengHui Weng
135 views86 slides
Java 8 與 retrolambda by
Java 8 與 retrolambdaJava 8 與 retrolambda
Java 8 與 retrolambdaJustin Lin
5K views45 slides
Javascript share by
Javascript shareJavascript share
Javascript shareXu Mac
84 views23 slides
JavaScript 快速複習 2017Q1 by
JavaScript 快速複習 2017Q1JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1Sheng-Han Su
2.7K views68 slides

What's hot(20)

Java8 lambda by koji lin
Java8 lambdaJava8 lambda
Java8 lambda
koji lin5.3K views
潜力无限的编程语言Javascript by jay li
潜力无限的编程语言Javascript潜力无限的编程语言Javascript
潜力无限的编程语言Javascript
jay li9.4K views
Introduction to Basic Haskell Components (In Chinese) by ChengHui Weng
Introduction to Basic Haskell Components (In Chinese)Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)
ChengHui Weng135 views
Java 8 與 retrolambda by Justin Lin
Java 8 與 retrolambdaJava 8 與 retrolambda
Java 8 與 retrolambda
Justin Lin5K views
Javascript share by Xu Mac
Javascript shareJavascript share
Javascript share
Xu Mac84 views
JavaScript 快速複習 2017Q1 by Sheng-Han Su
JavaScript 快速複習 2017Q1JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1
Sheng-Han Su2.7K views
Use Lambdas in Android by koji lin
Use Lambdas in AndroidUse Lambdas in Android
Use Lambdas in Android
koji lin1.9K views
Js的国(转载) by Leo Hui
Js的国(转载)Js的国(转载)
Js的国(转载)
Leo Hui756 views
Wind.js无障碍调试与排错 by jeffz
Wind.js无障碍调试与排错Wind.js无障碍调试与排错
Wind.js无障碍调试与排错
jeffz2K views
Lua 语言介绍 by gowell
Lua 语言介绍Lua 语言介绍
Lua 语言介绍
gowell1.2K views
ES5 introduction by otakustay
ES5 introductionES5 introduction
ES5 introduction
otakustay884 views
Introduction to C++ over CLI by 建興 王
Introduction to C++ over CLIIntroduction to C++ over CLI
Introduction to C++ over CLI
建興 王2.8K views
Clojure简介与应用 by Robert Hao
Clojure简介与应用Clojure简介与应用
Clojure简介与应用
Robert Hao1.5K views
Java Script 引擎技术 by bigqiang zou
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术
bigqiang zou2.5K views
Arrays的Sort算法分析 by Zianed Hou
Arrays的Sort算法分析Arrays的Sort算法分析
Arrays的Sort算法分析
Zianed Hou669 views
jQuery源码学习 by fangdeng
jQuery源码学习jQuery源码学习
jQuery源码学习
fangdeng436 views
認識 C++11 新標準及使用 AMP 函式庫作平行運算 by 建興 王
認識 C++11 新標準及使用 AMP 函式庫作平行運算認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算
建興 王3.2K views

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

C程式-函式與巨集 by
C程式-函式與巨集C程式-函式與巨集
C程式-函式與巨集艾鍗科技
42.6K views42 slides
Js is js(程劭非) (1) by
Js is js(程劭非) (1)Js is js(程劭非) (1)
Js is js(程劭非) (1)looneyren
758 views39 slides
Ch9 教學 by
Ch9 教學Ch9 教學
Ch9 教學hungchiayang1
467 views32 slides
Swift编程语言入门教程 中文版 by
Swift编程语言入门教程 中文版Swift编程语言入门教程 中文版
Swift编程语言入门教程 中文版Harvey Zhang
308 views15 slides
Java script closures by
Java script closuresJava script closures
Java script closuresskywalker1114
243 views14 slides
Java script closures by
Java script closuresJava script closures
Java script closuresskywalker1114
433 views14 slides

Similar to lambda/closure – JavaScript、Python、Scala 到 Java SE 7(20)

C程式-函式與巨集 by 艾鍗科技
C程式-函式與巨集C程式-函式與巨集
C程式-函式與巨集
艾鍗科技42.6K views
Js is js(程劭非) (1) by looneyren
Js is js(程劭非) (1)Js is js(程劭非) (1)
Js is js(程劭非) (1)
looneyren758 views
Swift编程语言入门教程 中文版 by Harvey Zhang
Swift编程语言入门教程 中文版Swift编程语言入门教程 中文版
Swift编程语言入门教程 中文版
Harvey Zhang308 views
Scala再探 by afeihehe
Scala再探Scala再探
Scala再探
afeihehe403 views
Python速成指南 by March Liu
Python速成指南Python速成指南
Python速成指南
March Liu8.7K views
Jscex:案例、阻碍、体会、展望 by jeffz
Jscex:案例、阻碍、体会、展望Jscex:案例、阻碍、体会、展望
Jscex:案例、阻碍、体会、展望
jeffz2.2K views
Jscex:案例、经验、阻碍、展望 by jeffz
Jscex:案例、经验、阻碍、展望Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望
jeffz1.9K views
Ihome inaction 篇外篇之fp介绍 by dennis zhuang
Ihome inaction 篇外篇之fp介绍Ihome inaction 篇外篇之fp介绍
Ihome inaction 篇外篇之fp介绍
dennis zhuang712 views
The Evolution of Async Programming (GZ TechParty C#) by jeffz
The Evolution of Async Programming (GZ TechParty C#)The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)
jeffz1.6K views
Matlab 在機率與統計的應用 by PingLun Liao
Matlab 在機率與統計的應用Matlab 在機率與統計的應用
Matlab 在機率與統計的應用
PingLun Liao6.6K views
Node.js开发体验 by QLeelulu
Node.js开发体验Node.js开发体验
Node.js开发体验
QLeelulu1.9K views

More from Justin Lin

Ch14 簡介 Spring Boot by
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring BootJustin Lin
872 views22 slides
Ch13 整合 Spring MVC/Security by
Ch13 整合 Spring MVC/SecurityCh13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityJustin Lin
280 views58 slides
Ch12 Spring 起步走 by
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走Justin Lin
274 views31 slides
Ch11 簡介 JavaMail by
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMailJustin Lin
157 views8 slides
Ch10 Web 容器安全管理 by
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Justin Lin
153 views30 slides
Ch09 整合資料庫 by
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫Justin Lin
233 views92 slides

More from Justin Lin(20)

Ch14 簡介 Spring Boot by Justin Lin
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring Boot
Justin Lin872 views
Ch13 整合 Spring MVC/Security by Justin Lin
Ch13 整合 Spring MVC/SecurityCh13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/Security
Justin Lin280 views
Ch12 Spring 起步走 by Justin Lin
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走
Justin Lin274 views
Ch11 簡介 JavaMail by Justin Lin
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMail
Justin Lin157 views
Ch10 Web 容器安全管理 by Justin Lin
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理
Justin Lin153 views
Ch09 整合資料庫 by Justin Lin
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫
Justin Lin233 views
Ch08 自訂標籤 by Justin Lin
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤
Justin Lin133 views
Ch07 使用 JSTL by Justin Lin
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTL
Justin Lin161 views
Ch06 使用 JSP by Justin Lin
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSP
Justin Lin250 views
Ch05 Servlet 進階 API、過濾器與傾聽器 by Justin Lin
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器
Justin Lin204 views
Ch04 會話管理 by Justin Lin
Ch04 會話管理Ch04 會話管理
Ch04 會話管理
Justin Lin238 views
Ch03 請求與回應 by Justin Lin
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應
Justin Lin236 views
Ch02 撰寫與設定 Servlet by Justin Lin
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 Servlet
Justin Lin352 views
CH1. 簡介 Web 應用程式 by Justin Lin
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式
Justin Lin1.2K views
14. 進階主題 by Justin Lin
14. 進階主題14. 進階主題
14. 進階主題
Justin Lin406 views
13.並行、平行與非同步 by Justin Lin
13.並行、平行與非同步13.並行、平行與非同步
13.並行、平行與非同步
Justin Lin237 views
12. 除錯、測試與效能 by Justin Lin
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能
Justin Lin153 views
11. 常用內建模組 by Justin Lin
11. 常用內建模組11. 常用內建模組
11. 常用內建模組
Justin Lin149 views
10. 資料永續與交換 by Justin Lin
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換
Justin Lin156 views
9. 資料結構 by Justin Lin
9. 資料結構9. 資料結構
9. 資料結構
Justin Lin292 views

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

  • 1. lambda/closure – JavaScript、Python、Scala 到 Java SE 7 林信良 http://openhome.cc caterpillar@openhome.cc
  • 3. 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
  • 4. 議程 • lambda • closure • 動靜之間 • 沒有 lambda/closure 的 Java • Java SE 7 lambda/closure 提案
  • 5. 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 /lambda/
  • 7. function doSome(param) { // 作些事 } var doSome = function(param) { // 作些事 }; function(param) { * Function literal // 作些事 * Function 實例 }; * new Function('param', '函式本體'); * Anonymous function
  • 8. 既然函式是物件,那麼可以作什麼? • 指定給別的變數 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');
  • 9. 既然可以指定給別的變數,就可以… • 作為引數傳入函式中 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);
  • 11. 走訪陣列 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>'); } );
  • 12. 可作為引數傳入函式?那就可以設計 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>'); } );
  • 15. Closure • 文言文…. – 函式物件建立時,自由變數(Free variable )綁定了當時作用範圍中的變數,使被綁定的 變數之作用範圍跟隨著被建立的函式物件 • 白話文 就是….
  • 17. 這是一個區域變數 function init() { var local = 10; setInterval( function() { alert(new Date() + ': ' + local); local++; }, 自由變數(Free variable) 3000); } window.onload = init; 網頁資源載入完成後執行一次
  • 18. • local這樣的變數對函式實字部份的宣告 來說,稱為自由變數(Free variable) • 自由變數真正的意義,必須結合函式實字 以外的環境才可以得知
  • 20. 實際的應用呢?… • 在 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;
  • 21. 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 綁定的是自由變數本身,而不是其值!
  • 24. My name is Python …. 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
  • 25. 函式定義 function max(m, n) { def max(m, n): if(m > n) { return m if m > n else n return m; } return n; } 匿名函式 function(m, n) { lambda m, n: m if m > n else n if(m > n) { return m; } return n; };
  • 26. 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: Closure list.append(primes[i]) num //= primes[i] else: i += 1 return factor # 傳回函式 factor = prepare_factor(1000) print(factor(100)) # 顯示 [2, 2, 5, 5]
  • 27. 當函式是物件時 • 可以根據需要傳遞給另一個名稱參考 • 不再被動呼叫,可主動指導別的函式動作 • 流程中不同演算,設計callback函式代換 • 可以形成 Closure 綁定自由變數(資源) • 可以從函式中傳回函式
  • 30. • 變數無需宣告就可以直接使用並指定值 • 除非特別使用global或nonlocal指明( Python 3),否則變數範圍(Scope) 總在指定值時建立
  • 31. def func(): def func(): x = 10 x = 10 def getX(): def getX(): return x return x def setX(n): def setX(n): x = n nonlocal x = n return (getX, setX) return (getX, setX) getX, setX = func() getX, setX = func() getX() # 10 getX() # 10 setX(20) setX(20) getX() # 10 getX() # 20
  • 32. 函式定義 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
  • 33. 函式定義 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
  • 34. 動態定型語言 • 型態資訊是在資料本身而不是變數 • 變數本身的型態是在執行時期運算得知, 也同一變數可以參考至各種型態的資料。 function max(m, n) { def max(m, n): if(m > n) { return m if m > n else n return m; } return n; } function(m, n) { max2 = lambda m, n: m if m > n else n if(m > n) { return m; } return n; };
  • 35. 靜態定型語言 • 根據資料的型態資訊,將變數及運算式進 行分類,型態資訊是在宣告的變數上 • 在執行時期變數的型態資訊無法改變,資 料只能被指定至同一種型態的變數 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
  • 36. 如果要設計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)) type inference val arr = Array(2, 5, 1, 7, 8) selection(arr, _ > _)
  • 38. 目前 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 的語法
  • 39. 目前 Java 沒有 lambda/closure • 所以無法設計 callback 函式 • 目前由 callback 物件來實現 語法上的冗長 也不僅是語法上的冗長
  • 40. 編譯器強迫你要加上 final 把外部res指定 public void doSome() { final int res = 10; ISome o = new ISome() { public void doIt() { 給區域變數res int result = res * 10; …. } } } 表面上…你綁定了res 事實上...編譯器只是建立一個區域變數res 所以編譯器強迫你要加上 final
  • 42. Lambdas in Java Preview • http://stronglytypedblog.blogspot.com/2010/06/lam bdas-in-java-preview-part-1-basics.html • http://stronglytypedblog.blogspot.com/2010/07/lam bdas-in-java-preview-part-2.html • http://stronglytypedblog.blogspot.com/2010/07/lam bdas-in-java-preview-part-3.html • http://stronglytypedblog.blogspot.com/2010/07/lam bdas-in-java-preview-part-4-proposal.html • http://stronglytypedblog.blogspot.com/2010/07/lam bdas-in-java-preview-part-5-apache.html
  • 43. #int(int) doubler = #(int x)(2*x); doubler.(3) 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; }
  • 44. Python max = lambda m, n: m if m > n else n max(10, 3) Scala val max: (Int, Int) => Int = (m, n) => if(m > n) m else n max(10, 3); Java #int(int, int) max = #(int x, int y) { if (x >= y) return x; else return y; }; max.(10, 3);
  • 45. Scala def selection(number: Array[Int], order: (Int, Int) => Boolean) { ... val o = order(a, b) … } … selection(arr, (a, b) => a > b) Java void selection(int[] array, #boolean(int, int) order) { ... boolean o = order.(a, b); … } … selection(arr, #(int a, int b)(a > b));
  • 46. 目前 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)));
  • 47. ##int(int)(int) sum = #(int x)(#(int y)(x+y)); 傳回函式 #int(int)
  • 48. 新的提案 • http://cr.openjdk.java.net/~briangoetz/lamb da/lambda-state-2.html – No more function types – More type inferencing – Scala-like syntax
  • 49. void selection(int[] array, #boolean(int, int) order) { ... boolean o = order.(a, b); … Function type } … selection(arr, #(int a, int b)(a > b)); public interface Order { public boolean compare(int a, int b); } void selection(int[] array, Order order) { ... boolean o = order.compare(a, b); … } SAM(Single Abstract Method) type … selection(arr, (a, b) -> {a > b}); More type inferencing Scala-like syntax
  • 50. 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); Much Better!!
  • 51. 我們需要? • Lambda/Closure • 類型推斷 • 單一抽象方法形態(SAM types) • 可利用現存的 API • 更多程式設計風格