DAY 3
5
Software Development

# Declarative 宣告式 vs. Imperative 命令式

Functional programming 是 Declarative Paradigm 的代表，邏輯為用較為抽象的程式碼，理解程式碼想要達到怎樣的目標，Function 之間不會互相共用 state 狀態，而 Imperative 代表 OOP 比較容易寫出狀態互相依賴的程式碼。

## Imperative is How to do

Imperative programming is a programming paradigm that uses statements that change a program's state.

• Example: OOP
• Stateful
• Can mutate state
• 常會有 Side Effect 發生

## Declarative is What to do

Declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.

• Example: FP
• Stateless: 你只要專心於當前算式，結束後再也不用管他
• Constants, immutability
• No Side Effect

``````// Imperative is How to do
var array = [3,2,1]
var total = 0
for( var i = 0 ; i <= array.length ; i ++ ){
total += array[i]
}
``````

``````// Declarative is What to do
var array = [3,2,1]
array.reduce( function( previous, current ){
return previous + current
})
``````

Declarative 則是可以直接知道做了 "什麼"，恩，看不太出來 Declarative 的好處啊?

• 轉小寫、去掉空格 `welcome to fp world`
• 輸出個別字串長度 > 3 字元的字串 `welcome world`
• 反轉 `world welcome`
``````// Imperative is How to do
// 'Welcome to FP world'
const doStuff = str => {
const lower = str.toLowerCase()  // 'welcome to fp world'
const words = lower.split('') // ['welcome', 'to', 'fp', 'world']

words.reverse() // ['world', 'fp', 'to', 'welcome']

for(let i in words) {
words[i] = words[i].trim()
} // ['world', 'fp', 'to', 'welcome']

let keepers = []

for(let i in words) {
if(words[i].length > 3) {
keepers.push(words[i])
}  // ['world', 'welcome']
}

return keepers.join(' ') // 'world welcome'
}

doStuff('Welcome to FP world')
``````

``````// Declarative is What to do
// 'Welcome to FP world'
const doStuff = _.compose(
join(' '),
_.filter(x => x.length > 3),
reverse,
_.map(trim),
split(' '),
toLowerCase
)
``````

Note. 感謝 Mike良葛格為什麼要學 Functional Programming? 留言中幫我釐清，並不是要屏棄 OOP 直接投入 FP，而是清楚他們的優缺點後，再套用到合適的專案，甚至也可以擷取各自優點兩個一起用。

## 來對照一下吧

BASIS FP OOP
Data Uses immutable data. Uses mutable data.
Execution The statements can be executed in any order. The statements should be executed in particular order.
Iteration Recursion is used for iterative data. Loops are used for iterative data.
Element The basic elements are Variables and Functions. The basic elements are objects and methods.
Use Often be used when there are few things with more operations. Often be used when there are many things with few operations.

#### 參考文章

``````如有錯誤或需要改進的地方，拜託跟我說。

``````

### 2 則留言

1
listennn08
iT邦高手 7 級 ‧ 2020-09-03 08:54:56

``````const words = lower.split(' ') // ['welcome', 'to', 'fp', 'world ']

``````

``````return keepers.join('-') // 'world welcome'
``````

hannahpun iT邦新手 5 級 ‧ 2020-09-03 10:54:25 檢舉

6

iT邦新手 3 級 ‧ 2020-09-04 08:01:08

Declarative is What to do 建議改為 Declarative is What's xxx ... 也就是宣告 xxx 是什麼。

• 命令式
``````function sum(array) {
// 做加總必須累加
let total = 0
for(let i = 0 ; i < array.length ; i ++ ){
total += array[i]
}
}

console.log(sum([3, 2, 1]));
``````
• 函數式
``````function sum(array) {
// 空陣列，總和就是 0
if(array.length === 0) {
return 0;
}

let tail = array.slice(1);
// 總和就是陣列第一項的值與餘下陣列的總和
}

console.log(sum([3, 2, 1]));
``````

`reduce` 本身在 FP 中，算是比較高階的抽象了，以上例來說，若你將 `sun``head + sum(tail)` 部份，想辦法再抽離出來，就會朝著 `reduce` 的方向重構，因此 `reduce` 的運用通常會封裝為函式，突顯其意圖，例如：

``````function sum(array) {
return array.reduce((accumulator, elem) => accumulator + elem);
}

console.log(sum([3, 2, 1]));
``````

``````// Imperative is How to do
// 'Welcome to FP world'
const doStuff = str => {
...
}

doStuff('Welcome to FP world')
``````

``````// Imperative is How to do stuff
// 'Welcome to FP world'
const doStuff = str => {
...
}

doStuff('Welcome to FP world')
``````

``````// Declarative is What to do
// 'Welcome to FP world'
const doStuff = _.compose(
join(' '),
_.filter(x => x.length > 3),
reverse,
_.map(trim),
split(' '),
toLowerCase
)
``````

``````// Declarative is What's stuff
// 'Welcome to FP world'
const stuff = _.compose(
join(' '),
_.filter(x => x.length > 3),
reverse,
_.map(trim),
split(' '),
toLowerCase
)
``````