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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
89
CSS polyfill とその未来
ken7253
0
310
Browser and UI #2 HTML/ARIA
ken7253
2
380
PEPCは何を変えようとしていたのか
ken7253
3
620
Browser and UI #1 CSS
ken7253
0
200
レビューのやり方を(ちょっと)整理した話
ken7253
1
630
オーバーロード関数の話 @Mita.ts #2
ken7253
0
190
フロントエンドカンファレンス北海道参加レポート
ken7253
0
110
Other Decks in Programming
See All in Programming
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
180
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
1.6k
パスワード再設定メールのURLについて知っておこう
uyuki234
0
160
Next.js: The final boss of Web Performance
guaca
0
280
全ての永続トークンを、生まれる前に消し去りたい!
sylph01
2
980
[2026-10-14](C)Re:ゼロから始める異世界生活〜始まりの終わりと終わりの始まり〜
tosite
0
110
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
2
800
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
160
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
1.1k
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.5k
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
380
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.7k
Featured
See All Featured
The Mindset for Success: Future Career Progression
greggifford
PRO
0
540
Exploring anti-patterns in Rails
aemeredith
4
540
SEO for Brand Visibility & Recognition
aleyda
0
4.8k
Designing Experiences People Love
moore
143
24k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
Statistics for Hackers
jakevdp
799
230k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.5k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
930
Facilitating Awesome Meetings
lara
57
7.2k
The Curse of the Amulet
leimatthew05
3
16k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
520
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
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));
まとめ 関数を設計するときにいくつか持つとよい視点がある。 純粋関数という視点を持つ 関数の設計を行う場合はシグニチャーに情報を持たせる