PL Lecture 10/28

Chunhao Weng
9 min readNov 4, 2020

Sub Programs Functional Abstraction

之前幾週停課,終於再次開始隔週的 PL Lecture。

順便做個整理,感恩爽燈。

PL Lecture — Subprogram 1

今天影片只談 Scoping, Coroutine, Parameter Passing Method 這三個主題,其他額外的會在後面補充。

Scoping

(主要以 Javascript 程式碼做舉例。)

這邊定義一個 sub1 ,接著呼叫 sub1。

Sub1 裡面有 定義 sub2, sub3, sub4 接著呼叫 sub3。

Javascript 最後的輸出只會有一種正確答案,但因為有兩種可能的語言設計,影片內兩種模式都來進行討論。

這邊順便定義之後會用的 notation。

黃色的框框:是 function 的 call stack ,也就是呼叫一個 function call 會 allocate run-time memory 給它。如果看到 global 就不屬於任何 function 。框框內會有 stack 存在的變數。

黑色的箭頭:Calling sequence ,就是從哪個 stack 網上長。

藍色的箭頭:今天的主題,Reference Environment。當一個 function 執行時,如何找他自己 scope 內找不到的變數、有哪些策略、這件事情會如何影響程式設計和 memory allocation 。

以這個例子來看,global 能看到一個 sub1 的東西,因為是在 global scope 定義的,因此長出一個 sub1 的 stack。

在 sub1 內其實 sub2, sub3, sub4 都是 visible 的,這邊老師手寫補上,不過因為只有呼叫 sub3 所以往上長 sub3 的 stack。

這時候 Reference Environment 要指回上一個 stack 還是第一個 stack ,就是程式設計可以不同的地方。

使用 Shallow Binding 會如何?

Shallow binding

這個例子是一種 Shallow Binding ,也就是會指回 caller ,也就是 stack 從哪裡長就指回哪裡。(sub3 藍色箭頭指回去 sub1)

回到例子,sub3 呼叫 sub4 的時候會把 sub2 當作參數帶入。

因此 sub4 的 subx 是指向 sub2 的,再長一個 sub2 的 stack。

最終呼叫 subx (也就是 sub2) ,然後 sub2 的 stack 要去 log x ,但此時要去找 x 在哪。

這時候根據 Shallow Binding 就會往上一個 caller 找,此時找到 x=4。

但是,Javascript 和大部分的語言實作並不用 Shallow Binding。

這跟之前提到 Dynamic Scoping 、 Static Scoping 是一模一樣的概念。

使用 Deep binding 會如何?

Deep binding

Deep binding 的 Reference Environment 會指向 function 被 define 時的 scope。 因此 compiler 在 compile 時就知道 Reference Environment 在哪裏。

Stack 前面的部分都一樣,global 的 sub1 被呼叫,因此會長一個 sub1 的 stack 。接著 sub1 呼叫 sub3,而 sub3 和接下來的 sub2, sub4 的 Reference Environment 會指向 sub1。

因此會找到 x=1。

Function Scoping 的例子

Function Scoping

例子兩個 f ,外面一個,裡面一個。

裡面的 f 用一個左括號、右括號,製造一個 local scope ,避免 name conflict。

一些Immediately Invoked Function Expression (IIFE) or Self Executing Anonymous Function 討論補充

https://stackoverflow.com/questions/440739/what-do-parentheses-surrounding-an-object-function-class-declaration-mean

https://en.wikipedia.org/wiki/Closure_(computer_programming)

https://www.tutorialspoint.com/Why-are-parenthesis-used-to-wrap-a-JavaScript-function-call

https://developer.mozilla.org/en-US/docs/Glossary/IIFE#:~:text=An%20IIFE%20(Immediately%20Invoked%20Function,soon%20as%20it%20is%20defined.&text=It%20is%20a%20design%20pattern,within%20the%20Grouping%20Operator%20()%20.

Global 會有一個 f ,也就是 x => x+1 的 f 。

而 => 的左手邊代表 argument ,箭頭右手邊代表 body。

https://en.wikipedia.org/wiki/Function_type

如果左手邊的 arguments 沒有需要的變數,就需要透過 Reference Environment 。

Global 定義了 f,接著為了 evaluate 括弧內的 expression ,會往上長一個 stack , anon 我猜是 anonymous 。

這裡面定義的 f 是指向這段 code (影片裡面的少 n*)n => n<= 0 ? 1 : n* f(n-1); ,為一個 recursion 關係。

接著 evaluate 的 f(2) 在 global 所以這裡面的 f 是指向 x => x+1 ,f(2) 會得到 n=3。

因為要繼承 function 被定義的 scope ,所以最上面 stack 的 f 的 Reference Environment 會指向 anon 。

判斷之後會 recursive 的找 f 也就是這個 function 被定義的 scope,最後得到 6 。

此時,最認真上課的 KK 發問了,就是之前關於 IIFE 的相關討論,這邊就先略過。

Function as Parameter 的例子

這個還算滿單純直覺,就先不紀錄。

Function as Return Value 的例子

這邊會先看到 addx ,是一個 Curry function。

https://en.wikipedia.org/wiki/Currying

addx 會吃一個 x 後 return 一個 function,因此可以用 addx 去創造一個什麼都 +5 的 add5 function 。

Add5 被定義的時候會長出一個 addx 的 stack ,return 值會是 y => x+y 這個 function 。

這個 function 是被這個 addx 的 stack 定義出來,因此之後 add5 被呼叫,Reference Environment (藍色箭頭)就要指向 function 被 define 的 Reference Environment。

很溫暖的爽燈還問大家有沒有問題。

接著執行 add5 ,長出一個 add5 的 stack ,因為是用 y => x+y 這個 function 因此 Reference Environment (藍色箭頭)也是指向同一個地方。

爽燈說這邊跟一般的 C 或 C++ 的程式不同,執行完 stack 不會被回收。

當允許 Function as Return Value 的時候, stack 必須要保留一些 被包起來的 Environment。

在描述這些的關鍵字:Curry function, higher order function, Closure

幾個重點:

如果程式語言要支援 Functions as Returned Values…

Run-time stack 必須用 linked list 實作(不能是 array structure)。原本不支援的 JavaScript 透過包一層來支援 arrow function。

Run-time stack 不會直直往上長,比較像 tree。

Object 要看 run-time 或 interpreter 怎麼實作 garbage collector。

目前大部分的熱門語言都用 Deep Binding ,以上就是 Scoping 的一些討論。

未來遇到一個程式語言,知道他是 Dynamic 或 Static Scoping, Deep 或 Shallow binding 就比較好掌握這個語言的行為。

Sign up to discover human stories that deepen your understanding of the world.

Chunhao Weng
Chunhao Weng

Written by Chunhao Weng

Random notes for personal use.

No responses yet

Write a response