Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
関数型プログラミングの考え方を取り入れて予測しやすいコードを書く
Search
ken7253
October 02, 2023
Programming
240
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
関数型プログラミングの考え方を取り入れて予測しやすいコードを書く
社内LT会にて発表した資料です。
ken7253
October 02, 2023
More Decks by ken7253
See All by ken7253
Firefoxにコントリビューションして得られた学び
ken7253
2
190
バンドルサイズを半減させた話 @Browser and UI #3
ken7253
0
88
CSS polyfill とその未来
ken7253
0
300
Browser and UI #2 HTML/ARIA
ken7253
2
380
PEPCは何を変えようとしていたのか
ken7253
3
600
Browser and UI #1 CSS
ken7253
0
190
レビューのやり方を(ちょっと)整理した話
ken7253
1
630
オーバーロード関数の話 @Mita.ts #2
ken7253
0
180
フロントエンドカンファレンス北海道参加レポート
ken7253
0
100
Other Decks in Programming
See All in Programming
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
440
WebRTC映像をAirPlayに対応させる挑戦.pdf
monolithic_adam
0
320
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
2
310
速習iPhone Duo対応
yuukiw00w
2
850
カツオ、ご期待ください
suneo3476
0
110
選挙速報を多くのユーザーへ 届ける Live Activities 設計
hamayokokuririn
0
180
iOSDC2026登壇資料.pdf
riofujimon
0
200
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
240
setup-vp GitLab対応の裏側
naokihaba
0
140
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
380
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
130
一人だけ、Kiroが静止する日
hideg
0
130
Featured
See All Featured
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
Why Our Code Smells
bkeepers
PRO
340
58k
Navigating Weather and Climate Data
rabernat
0
540
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Test your architecture with Archunit
thirion
2
2.4k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
850
Making the Leap to Tech Lead
cromwellryan
135
10k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
420
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
390
How to Talk to Developers About Accessibility
jct
2
560
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Transcript
Introduction Functional Programming 関数型プログラミングの考え方を取り入れて予測しやすいコードを書く
ken7253 Frontend developer 技術記事を書いたりするのが趣味。 最近はNext.jsを使ったアプリケーションを書いています。 インターフェイス設計やアクセシビリティ・SSG関連の技術に興味があります。 https://github.com/ken7253 https://zenn.dev/ken7253 https://dairoku-studio.com
前日譚 「なっとく!関数型プログラミング」 という本を買って読んでいました。 参考になる内容が多かった 関数型の考え方を紹介 ガチガチの関数型は難しいけど 少し取り入れてコードの品質を上げる
関数型プログラミングの考え方を部分的に採用し フロントエンドでも馴染み深いライブラリといえば?
None
話すこと 純粋関数について シグニチャーを意識して関数を作る
純粋関数
関数の分類の一つで特に関数型プログラミングで重要な考え方 下記の条件を全て満たした関数のことを純粋関数と呼ぶ 引数のみを利用する 戻り値は常に一つだけ 既存の変数を変更しない 純粋関数とはなにか
「引数のみを利用する」とは下記のようなこと グローバル変数を参照したり、時刻に依存するコードなど。 純粋関数の条件 // 🙆♂ 純粋関数 const pureFunc = (x:number,
y:number): number => { return x * y; }; // 🙅♂ 純粋関数ではない let x = 0; let y = 0; const notPureFunc = (): number => { return x * y; };
戻り値は常に1つだけ。 状況によってエラーを発生させたり、そもそも値を返さない場合がある関数など。 純粋関数の条件 // 🙅♂ 純粋関数ではない const notPureFunc = (a:
number): number | void => { if (a === 0) { throw new Error('Error'); } else if (a >= 100) { return a } // 値を返さない場合もある }
既存の変数を変更しない Array#push() や Array#reverse() などのメソッド、 var / let に対する再代入 などを関数の内部で呼び出して、既存の値を変更している場合など
純粋関数の条件 let num = 0; // 🙆♂ 純粋関数 const pureFunc = (n:number): number => { return n + 1; }; pureFunc(num); // num => 0 let num = 0; // 🙅♂ 純粋関数ではない const notPureFunc = (n:number): number => { return n++; }; notPureFunc(num); // num => 1
テストしやすい 意図しない挙動を起こしづらい コードの挙動が予測しやすい 副作用を分離することは 「臭いものに蓋をする」 だけに見える。 実際は、処理同士の繋がりが 型によって可視化 されてわかりやすいコードになる。 純粋関数だと何が嬉しいか
シグニチャー
シグニチャーとはなにか シグニチャー(シグネチャ)とは下記の情報をまとめた呼称 関数名 引数の型 返り値の型
下記のような関数があるとする。 この状態で何をしている関数であるか理解できる人は少ない。 シグニチャーの情報が少ない場合 export const foo: (a: any, b: any):
any => { // 外部からは見えない何らかの処理 }
シグニチャーをより正確にしてみる これにテストを追加してみる。 こうすることで(テストが無くても)ある程度挙動が推測できる。 シグニチャーの情報が少ない場合 export const sum = (first: number,
second: number): number | TypeError => { // 外部からは見えない何らかの処理 } import { sum } from "./sum" describe('与えられた引数を足し算して返却するsum関数', () => { test('自然数同士の足し算が正しく実行されること', () => {/* 省略 */}) test('引数のどちらかにNaNが渡された場合TypeErrorを返却すること', () => {/* 省略 */}) test('引数のどちらかにInfinityが渡された場合TypeErrorを返却すること', () => {/* 省略 */}) })
例としてこの関数を実際に使ってみる。 このようにシグニチャーから関数の使い方が理解できる。 情報の多い関数は適切に使用できる import { sum } from "./sum"; import
{ sendError } from "./sendError"; const [x,y] = [10, 20]; const sumResult = sum(x,y); // number | TypeError // そのままだと型が合わないので型ガードを利用する。 if (sumResult instanceof TypeError) { // sendError = (error: Error) => void; sendError(sumResult); // sendError(); はエラー情報をサーバーに送る処理として考える } else { console.log(sumResult); }
具体的なコードで見てみる 複数の要素の中から一番高さを持つ要素を探してコンソールに出力する処理 一つの関数にいろいろやらせている例 このようなコードがあった場合、次のように変えてみる。 // 入出力の情報がないので説明のための関数名が長くなりがち const displayHighestElementByElementList = ()
=> { // 要素の取得 const elements = document.querySelectorAll('.some-class'); const elementList = Array.from(elements); // 比較とソート const sortedFromClientHeight = [...elementList].sort((prev, next) => { return next.clientHeight - prev.clientHeight; }); // コンソールへの出力 console.log(sortedFromClientHeight[0]); }; displayHighestElementByElementList();
具体的なコードで見てみる 複数の要素の中から一番高さを持つ要素を探してコンソールに出力する処理 要素の取得 -> 比較関数 -> 出力 という値の流れが掴みやすい。 入出力の型情報があることで挙動が推測しやすい関数になる。 //
与えられた要素の配列から一番高さを持つ要素を返す関数 const getHighestElement = (elementList: Element[]): Element => { const sorted = [...elementList].sort((prev, next) => { return next.clientHeight - prev.clientHeight }); return sorted[0]; }; // 要素の取得 const elementList = Array.from(document.querySelectorAll('.some-class')); // コンソールへの出力 console.log(getHighestElement(elementList));
具体的なコードで見てみる 複数の要素の中から一番高さを持つ要素を探してコンソールに出力する処理 もっと関数型っぽい書き方だとこう。 配列のメソッドをうまく使って無駄なく宣言的に記述する。 // 与えられた要素の配列から一番高さを持つ要素を返す関数 const getHighestElement = (elementList:
Element[]): Element => elementList.reduce((acc, current) => acc.clientHeight >= current.clientHeight ? acc : current ); // 要素の取得 const elementList = Array.from(document.querySelectorAll(".some-class")); // コンソールへの出力 console.log(getHighestElement(elementList));
まとめ 関数を設計するときにいくつか持つとよい視点がある。 純粋関数という視点を持つ 関数の設計を行う場合はシグニチャーに情報を持たせる