SlideShare ist ein Scribd-Unternehmen logo
1 von 52
Downloaden Sie, um offline zu lesen
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 綁定自由變數(資源)
•   可以從函式中傳回函式
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

Weitere ähnliche Inhalte

Was ist angesagt?

Java8 lambda
Java8 lambdaJava8 lambda
Java8 lambdakoji lin
 
潜力无限的编程语言Javascript
潜力无限的编程语言Javascript潜力无限的编程语言Javascript
潜力无限的编程语言Javascriptjay li
 
Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)ChengHui Weng
 
Java 8 與 retrolambda
Java 8 與 retrolambdaJava 8 與 retrolambda
Java 8 與 retrolambdaJustin Lin
 
Javascript share
Javascript shareJavascript share
Javascript shareXu Mac
 
JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1Sheng-Han Su
 
Use Lambdas in Android
Use Lambdas in AndroidUse Lambdas in Android
Use Lambdas in Androidkoji lin
 
Js的国(转载)
Js的国(转载)Js的国(转载)
Js的国(转载)Leo Hui
 
Wind.js无障碍调试与排错
Wind.js无障碍调试与排错Wind.js无障碍调试与排错
Wind.js无障碍调试与排错jeffz
 
Lua 语言介绍
Lua 语言介绍Lua 语言介绍
Lua 语言介绍gowell
 
ES5 introduction
ES5 introductionES5 introduction
ES5 introductionotakustay
 
Introduction to C++ over CLI
Introduction to C++ over CLIIntroduction to C++ over CLI
Introduction to C++ over CLI建興 王
 
Clojure简介与应用
Clojure简介与应用Clojure简介与应用
Clojure简介与应用Robert Hao
 
Java Script 引擎技术
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术bigqiang zou
 
Arrays的Sort算法分析
Arrays的Sort算法分析Arrays的Sort算法分析
Arrays的Sort算法分析Zianed Hou
 
jQuery源码学习
jQuery源码学习jQuery源码学习
jQuery源码学习fangdeng
 
認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算建興 王
 

Was ist angesagt? (20)

Java8 lambda
Java8 lambdaJava8 lambda
Java8 lambda
 
潜力无限的编程语言Javascript
潜力无限的编程语言Javascript潜力无限的编程语言Javascript
潜力无限的编程语言Javascript
 
Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)
 
Java 8 與 retrolambda
Java 8 與 retrolambdaJava 8 與 retrolambda
Java 8 與 retrolambda
 
Javascript share
Javascript shareJavascript share
Javascript share
 
JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1
 
Hi Haskell
Hi HaskellHi Haskell
Hi Haskell
 
Use Lambdas in Android
Use Lambdas in AndroidUse Lambdas in Android
Use Lambdas in Android
 
Js的国(转载)
Js的国(转载)Js的国(转载)
Js的国(转载)
 
Sun java
Sun javaSun java
Sun java
 
Wind.js无障碍调试与排错
Wind.js无障碍调试与排错Wind.js无障碍调试与排错
Wind.js无障碍调试与排错
 
Lua 语言介绍
Lua 语言介绍Lua 语言介绍
Lua 语言介绍
 
Scala+RDD
Scala+RDDScala+RDD
Scala+RDD
 
ES5 introduction
ES5 introductionES5 introduction
ES5 introduction
 
Introduction to C++ over CLI
Introduction to C++ over CLIIntroduction to C++ over CLI
Introduction to C++ over CLI
 
Clojure简介与应用
Clojure简介与应用Clojure简介与应用
Clojure简介与应用
 
Java Script 引擎技术
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术
 
Arrays的Sort算法分析
Arrays的Sort算法分析Arrays的Sort算法分析
Arrays的Sort算法分析
 
jQuery源码学习
jQuery源码学习jQuery源码学习
jQuery源码学习
 
認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算
 

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

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

Ähnlich wie lambda/closure – JavaScript、Python、Scala 到 Java SE 7 (20)

C程式-函式與巨集
C程式-函式與巨集C程式-函式與巨集
C程式-函式與巨集
 
Js is js(程劭非) (1)
Js is js(程劭非) (1)Js is js(程劭非) (1)
Js is js(程劭非) (1)
 
Ch9 教學
Ch9 教學Ch9 教學
Ch9 教學
 
Swift编程语言入门教程 中文版
Swift编程语言入门教程 中文版Swift编程语言入门教程 中文版
Swift编程语言入门教程 中文版
 
Java script closures
Java script closuresJava script closures
Java script closures
 
Java script closures
Java script closuresJava script closures
Java script closures
 
Ch9
Ch9Ch9
Ch9
 
Scala+spark 2nd
Scala+spark 2ndScala+spark 2nd
Scala+spark 2nd
 
Python變數與資料運算
Python變數與資料運算Python變數與資料運算
Python變數與資料運算
 
Scala再探
Scala再探Scala再探
Scala再探
 
Python速成指南
Python速成指南Python速成指南
Python速成指南
 
Appendix B 範例
Appendix B 範例Appendix B 範例
Appendix B 範例
 
Jscex:案例、阻碍、体会、展望
Jscex:案例、阻碍、体会、展望Jscex:案例、阻碍、体会、展望
Jscex:案例、阻碍、体会、展望
 
Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望
 
Ihome inaction 篇外篇之fp介绍
Ihome inaction 篇外篇之fp介绍Ihome inaction 篇外篇之fp介绍
Ihome inaction 篇外篇之fp介绍
 
Ppt 120-126
Ppt 120-126Ppt 120-126
Ppt 120-126
 
Ppt 120-126
Ppt 120-126Ppt 120-126
Ppt 120-126
 
The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)
 
Matlab 在機率與統計的應用
Matlab 在機率與統計的應用Matlab 在機率與統計的應用
Matlab 在機率與統計的應用
 
Node.js开发体验
Node.js开发体验Node.js开发体验
Node.js开发体验
 

Mehr von Justin Lin

Ch14 簡介 Spring Boot
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring BootJustin Lin
 
Ch13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityCh13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityJustin Lin
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走Justin Lin
 
Ch11 簡介 JavaMail
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMailJustin Lin
 
Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Justin Lin
 
Ch09 整合資料庫
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫Justin Lin
 
Ch08 自訂標籤
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤Justin Lin
 
Ch07 使用 JSTL
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTLJustin Lin
 
Ch06 使用 JSP
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSPJustin Lin
 
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Justin Lin
 
Ch04 會話管理
Ch04 會話管理Ch04 會話管理
Ch04 會話管理Justin Lin
 
Ch03 請求與回應
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應Justin Lin
 
Ch02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletJustin Lin
 
CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式Justin Lin
 
14. 進階主題
14. 進階主題14. 進階主題
14. 進階主題Justin Lin
 
13.並行、平行與非同步
13.並行、平行與非同步13.並行、平行與非同步
13.並行、平行與非同步Justin Lin
 
12. 除錯、測試與效能
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能Justin Lin
 
11. 常用內建模組
11. 常用內建模組11. 常用內建模組
11. 常用內建模組Justin Lin
 
10. 資料永續與交換
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換Justin Lin
 
9. 資料結構
9. 資料結構9. 資料結構
9. 資料結構Justin Lin
 

Mehr von Justin Lin (20)

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

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 綁定自由變數(資源) • 可以從函式中傳回函式
  • 28.
  • 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 • 更多程式設計風格