[go: up one dir, main page]

SlideShare a Scribd company logo
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
Ad

Recommended

Java 開發者的函數式程式設計
Java 開發者的函數式程式設計
Justin Lin
 
千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7
Justin Lin
 
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Justin Lin
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析
Justin Lin
 
Ecmascript
Ecmascript
jay li
 
Ecma script edition5-小试
Ecma script edition5-小试
lydiafly
 
Scala function-and-closures
Scala function-and-closures
wang hongjiang
 
functional-scala
functional-scala
wang hongjiang
 
Java8 lambda
Java8 lambda
koji lin
 
潜力无限的编程语言Javascript
潜力无限的编程语言Javascript
jay li
 
Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)
ChengHui Weng
 
Java 8 與 retrolambda
Java 8 與 retrolambda
Justin Lin
 
Javascript share
Javascript share
Xu Mac
 
JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1
Sheng-Han Su
 
Hi Haskell
Hi Haskell
Jifeng Deng
 
Use Lambdas in Android
Use Lambdas in Android
koji lin
 
Js的国(转载)
Js的国(转载)
Leo Hui
 
Sun java
Sun java
softwaredesigner
 
Wind.js无障碍调试与排错
Wind.js无障碍调试与排错
jeffz
 
Lua 语言介绍
Lua 语言介绍
gowell
 
Scala+RDD
Scala+RDD
Yuanhang Wang
 
ES5 introduction
ES5 introduction
otakustay
 
Introduction to C++ over CLI
Introduction to C++ over CLI
建興 王
 
Clojure简介与应用
Clojure简介与应用
Robert Hao
 
Java Script 引擎技术
Java Script 引擎技术
bigqiang zou
 
Arrays的Sort算法分析
Arrays的Sort算法分析
Zianed Hou
 
jQuery源码学习
jQuery源码学习
fangdeng
 
認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算
建興 王
 
那些函數語言Tutorial沒有教我的事
那些函數語言Tutorial沒有教我的事
YC Ling
 
Programming python - part 1
Programming python - part 1
Che-Cheng Hsu
 

More Related Content

What's hot (20)

Java8 lambda
Java8 lambda
koji lin
 
潜力无限的编程语言Javascript
潜力无限的编程语言Javascript
jay li
 
Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)
ChengHui Weng
 
Java 8 與 retrolambda
Java 8 與 retrolambda
Justin Lin
 
Javascript share
Javascript share
Xu Mac
 
JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1
Sheng-Han Su
 
Hi Haskell
Hi Haskell
Jifeng Deng
 
Use Lambdas in Android
Use Lambdas in Android
koji lin
 
Js的国(转载)
Js的国(转载)
Leo Hui
 
Sun java
Sun java
softwaredesigner
 
Wind.js无障碍调试与排错
Wind.js无障碍调试与排错
jeffz
 
Lua 语言介绍
Lua 语言介绍
gowell
 
Scala+RDD
Scala+RDD
Yuanhang Wang
 
ES5 introduction
ES5 introduction
otakustay
 
Introduction to C++ over CLI
Introduction to C++ over CLI
建興 王
 
Clojure简介与应用
Clojure简介与应用
Robert Hao
 
Java Script 引擎技术
Java Script 引擎技术
bigqiang zou
 
Arrays的Sort算法分析
Arrays的Sort算法分析
Zianed Hou
 
jQuery源码学习
jQuery源码学习
fangdeng
 
認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算
建興 王
 
Java8 lambda
Java8 lambda
koji lin
 
潜力无限的编程语言Javascript
潜力无限的编程语言Javascript
jay li
 
Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)
ChengHui Weng
 
Java 8 與 retrolambda
Java 8 與 retrolambda
Justin Lin
 
Javascript share
Javascript share
Xu Mac
 
JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1
Sheng-Han Su
 
Use Lambdas in Android
Use Lambdas in Android
koji lin
 
Js的国(转载)
Js的国(转载)
Leo Hui
 
Wind.js无障碍调试与排错
Wind.js无障碍调试与排错
jeffz
 
Lua 语言介绍
Lua 语言介绍
gowell
 
ES5 introduction
ES5 introduction
otakustay
 
Introduction to C++ over CLI
Introduction to C++ over CLI
建興 王
 
Clojure简介与应用
Clojure简介与应用
Robert Hao
 
Java Script 引擎技术
Java Script 引擎技术
bigqiang zou
 
Arrays的Sort算法分析
Arrays的Sort算法分析
Zianed Hou
 
jQuery源码学习
jQuery源码学习
fangdeng
 
認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算
建興 王
 

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

那些函數語言Tutorial沒有教我的事
那些函數語言Tutorial沒有教我的事
YC Ling
 
Programming python - part 1
Programming python - part 1
Che-Cheng Hsu
 
JavaScript 快速跳坑指南
JavaScript 快速跳坑指南
MuJingTsai
 
nodeMCU IOT教學02 - Lua語言
nodeMCU IOT教學02 - Lua語言
吳錫修 (ShyiShiou Wu)
 
nodeMCU IOT教學02 - Lua語言
nodeMCU IOT教學02 - Lua語言
吳錫修 (ShyiShiou Wu)
 
JCConf 2023 - 深入淺出 Java 21 功能
JCConf 2023 - 深入淺出 Java 21 功能
Joseph Kuo
 
180518 ntut js and node
180518 ntut js and node
Peter Yi
 
Learn Haskell The Easy Way
Learn Haskell The Easy Way
YC Ling
 
A Tour of Go 學習筆記
A Tour of Go 學習筆記
昕暐 黃
 
JCConf 2024 - Java 22 & 23 新功能介紹
JCConf 2024 - Java 22 & 23 新功能介紹
Joseph Kuo
 
張逸 - 研究所 / 轉學考計算機概論 、公職計算機概要 - 程式語言 - 試閱版
張逸 - 研究所 / 轉學考計算機概論 、公職計算機概要 - 程式語言 - 試閱版
逸 張
 
twMVC#27 | C# 7.0 新功能介紹
twMVC#27 | C# 7.0 新功能介紹
twMVC
 
JavaScript 技術手冊第 5 章
JavaScript 技術手冊第 5 章
Justin Lin
 
C程式-函式與巨集
C程式-函式與巨集
艾鍗科技
 
簡單介紹JavaScript參數傳遞
簡單介紹JavaScript參數傳遞
林儀泰 Tommy Lin
 
Ch9 教學
Ch9 教學
hungchiayang1
 
Java SE 7 技術手冊投影片第 05 章 - 物件封裝
Java SE 7 技術手冊投影片第 05 章 - 物件封裝
Justin Lin
 
Java SE 7 技術手冊第五章草稿 - 何謂封裝?
Java SE 7 技術手冊第五章草稿 - 何謂封裝?
Justin Lin
 
Java functional api
Java functional api
javakidxxx
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
Shengyou Fan
 
那些函數語言Tutorial沒有教我的事
那些函數語言Tutorial沒有教我的事
YC Ling
 
Programming python - part 1
Programming python - part 1
Che-Cheng Hsu
 
JavaScript 快速跳坑指南
JavaScript 快速跳坑指南
MuJingTsai
 
JCConf 2023 - 深入淺出 Java 21 功能
JCConf 2023 - 深入淺出 Java 21 功能
Joseph Kuo
 
180518 ntut js and node
180518 ntut js and node
Peter Yi
 
Learn Haskell The Easy Way
Learn Haskell The Easy Way
YC Ling
 
A Tour of Go 學習筆記
A Tour of Go 學習筆記
昕暐 黃
 
JCConf 2024 - Java 22 & 23 新功能介紹
JCConf 2024 - Java 22 & 23 新功能介紹
Joseph Kuo
 
張逸 - 研究所 / 轉學考計算機概論 、公職計算機概要 - 程式語言 - 試閱版
張逸 - 研究所 / 轉學考計算機概論 、公職計算機概要 - 程式語言 - 試閱版
逸 張
 
twMVC#27 | C# 7.0 新功能介紹
twMVC#27 | C# 7.0 新功能介紹
twMVC
 
JavaScript 技術手冊第 5 章
JavaScript 技術手冊第 5 章
Justin Lin
 
C程式-函式與巨集
C程式-函式與巨集
艾鍗科技
 
簡單介紹JavaScript參數傳遞
簡單介紹JavaScript參數傳遞
林儀泰 Tommy Lin
 
Java SE 7 技術手冊投影片第 05 章 - 物件封裝
Java SE 7 技術手冊投影片第 05 章 - 物件封裝
Justin Lin
 
Java SE 7 技術手冊第五章草稿 - 何謂封裝?
Java SE 7 技術手冊第五章草稿 - 何謂封裝?
Justin Lin
 
Java functional api
Java functional api
javakidxxx
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
Shengyou Fan
 
Ad

More from Justin Lin (20)

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

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 • 更多程式設計風格