N個の要件をN個の要素で書く
「N個の要件がある」ということをコードをパッと見た時に伝わると良い
メンタルモデルとコードを一致させる
要件と要素を一致させる
常にできるわけではないが、できるだけそうなるように書く
Interfaceの話ではなく、bodyの話
概念の構成の話ではなく、表現・表層の話
コードを書く過程のだいぶ最後の話をしていることに注意する
その関数の責務や流れを明確に言語化し、それをコードで表現する
結果的に、これが内部の関数の要件決めに繋がる
この関数を書いている過程で、内部の関数のInterfaceが決まる
再帰的に適用していくことでトップダウンにコードが作られる
例
内部の処理がN個のフローを行う関数を考えるとわかりやすい
例えば、以下のようなことを行うmain関数を考える
ユーザのデータを処理し、
フィルタリング、
変換、
集計、
フォーマット、
送信
以下のようなコードになっているとわかりやすい
code:ts
async function process(users: User[]) {
const activeUsers = filterActiveUsers(users);
const transformedUsers = transformUsers(activeUsers);
const aggregatedData = aggregateData(transformedUsers);
const formattedData = formatData(aggregatedData);
return await sendData(formattedData);
}
code:fs
let process users =
users
|> filterActiveUsers
|> transformUsers
|> aggregateData
|> formatData
|> sendData
code:hs
process = sendData . formatData . aggregateData . transformUsers . filterActiveUsers
他の例
「レベルA(クリアで簡潔)」もまだ改善の余地があると思うmrsekut.icon
列挙しない書き方と比較するとわかりやすさがダンチ
書かせてみて思ったが、自分でレベルCのようなコードを書くの逆に難しいな(?)
フローじゃないときも同様
N行で書かれてなくても良いから、N個のことを行っていることがわかるようになっていれば良い
寧ろフローじゃないほうが、宣言的に書きやすいmrsekut.icon
例えば、ReactのComponentを書くときに、
そのUI Compnentが満たすべき要件は「表示」以外にも何個かあったりする
ここをタップしたときに、ここまでスクロールする、とか
ここをタップしたときに、これが表示される、とか
それらのまとまりでHooksに切ったり、Componentに切ったりして、パッと見で何をやってるのかわかるようにする
リスト系の関数は、「基底部分」と「それ以外」という2つの要件を満たせばできる
なので2行で書いている、と言える
sumの例
code:hs
sum [] = 0
sum (x:xs) = x + sum xs
2つの要件がある
空配列のときは0を返す
それ以外の場合は、先頭要素に、残りのsumを足す
じゃっかん違う話な気もしてきたmrsekut.icon