closure

Page content

前言

最近看 JS 時看到 closure,在 Haskell 中也有一樣的字

JavaScriopt

從理論來說,所有函數都是 closure

從實作角度來說

符合下列兩個其中之一的

  • 用了自由變數
  • 即使創建他的上下文已經銷毀,他仍然存在

用了自由變數

const name = "Heisenberg"

function sayMyName() {
    console.log(name);  // Heisenberg
}

sayMyName();

namesayMyName 這個 function 外面,卻可以在 sayMyName 這個 function 裡面拿到他的值。

創建他的上下文已經銷毀,他仍然存在

在函數裡面 return

function outer() {

    outerVar = '外層變數';
    
    function inner () {
        console.log(outerVar)
    }
    return inner;
}

innerFunc = outer();
innerFunc();

另一個例子

function compose (f, g) {
    return function (x) {
        return f ( g(x) );
    }
}

Haskell

Haskell Wiki 對 closure 的定義

A closure, the opposite of a combinator, is a function that makes use of free variables in its definition. It ‘closes’ around some portion of its environment.

combinator 是沒有 free variable 的 function 或定義

而 closure 是他的相反,是有 free variable

f x = (\y -> x + y)

f returns a closure, because the variable x, which is bound outside of the lambda abstraction is used inside its definition.

An interesting side note: the context in which x was bound shouldn’t even exist anymore, and wouldn’t, had the lambda abstraction not closed around x.

f . g = \x -> f ( g(x) )

在 $\lambda x$ 中,f 和 g 沒有被定義,他們是 自由變數(free variables),他們的定義由上層函數提供。

跑到這裡時,會用上層函數提供的環境把它「封閉」起來,包進自己的 function scope ($ \lambda x $) 中。

由 外層函數 提供 內層函數 中 自由變數 的 閉包。

參考資料

JavaScript深入之闭包 專欄文章:Java Lambda Tutorial