465 Views
May 28, 26
スライド概要
Rich Hickeyの有名なプレゼン"Simple Made Easy"をより踏み込んで解説します。
cf. 2019年版: https://www.docswell.com/s/lagenorhynque/57VRMG-simple-made-easy-made-easy
「楽しく楽にcoolにsmartに」を理想とするprogrammer/philosopher/liberalist/realist。 好きな言語はClojure, Haskell, Elixir, English, français, русский。 読書、プログラミング、語学、法学、数学が大好き! イルカと海も大好き🐬
"Simple Made Easy" Made Easier に学ぶsimplicity Clojure #lispmeetup 1
🐬カマイルカ lagénorhynque 関数型プログラミング(言語)の愛好者/実践者 特にClojure, Haskell, Flixがエレガントで好き 関数型まつり2026の運営スタッフ(座長のひとり) 主に(CfPを含む)メインコンテンツの準備を担当 株式会社スマートラウンドのシニアエンジニア スタートアップと投資家のやり取りを効率化する データ管理プラットフォームを開発 ソフトウェア設計/開発とともに会計/財務/法務 について探求するのも好き 2
年 月の関数型まつり2026で登壇予定🐬 [PR] 2026 7 速習FP in Scala with Flix: Flix言語で親しむ純粋関数型のコード設計 3
視点でのFlixの紹介記事を書きました🐬 [PR] Clojurian が出会ったsimple志向なJVM関数型言語Flix ——ファーストインプレッション Clojurian 4
関数型言語 年 月 での発表 Fun Fun Functional (2) Lightning Talks!! (2019 7 ) の設計思想を理解しよう [書き起こし記事] "simple"と"easy"はどう違う? Simple Made Easyを解説 Part1 "Simple Made Easy" Made Easy: Clojure 5
今回のテーマ (-> (simple-made-easy-made-easy) revisit ; "Simple Made Easy" Made Easy deepen ; Clojure / extend) ; Clojure 「 近年の 」をおさらい エコシステム コミュニティの進化を深掘り の範囲に留まらないより一般的な示唆へと展開 6
と という言葉 とは と の意味 と の関係 なぜ を重視するのか どのように にするのか に見る と の区別のより抽象的(メタ)な示唆 1. simple easy 2. "Simple Made Easy" 3. simple easy 4. simple easy 5. simplicity 6. simple 7. Clojure simplicity 8. simple easy 7
1. simple と easy という言葉 8
コミュニティにおける simple 明確に定義された特別な意味がある easy と混同されやすいが概念的にまったく違う Clojureとは simple さ(simplicity)を追求した言語 あらゆる場面で非常に重視されている概念 設計の良し悪しを図る指標のひとつ Clojure 9
とは 2. "Simple Made Easy" 10
Simple Made Easy (at Strange Loop 2011) 作者Rich Hickeyによる極めて有名な発表 コミュニティで simple の概念が浸透するきっかけ 日本ではタイトルも趣旨も(特にClojurian以外から) わりと誤解されているかも Clojure cf. Simplicity Matters (at RailsConf 2012) · eed3si9n シンプルさの必要性 11
タイトル"Simple Made Easy"の意味 敢えて訳せば「simple簡単解説」 例えば Word Power Made Easy という本がある 英語の文法的には: X makes Y easy. → Y is made easy [by X]. → Y made easy [by X] ( simple easy simple easy ? 簡単になったY) 本題の と を掛けた言葉遊びでもある を追求すると にもなる 英語的にも内容的にもちょっと苦しい解釈 12
3. simple と easy の意味 13
simple の意味 simple < simplex (= sim- + plex) ラテン語 simplex 原義: 「一折り」「一編み」「一捻り」 「単一の役割」「単一の責務」「単一の概念」「単 一の次元」 ※「単一の実体/操作」 ではない 客観的な概念: 設計対象の構造の単純さ 対義語: complex (= com- + plex) 原義: 「絡まり合った」「折り重なった」「もつれ た」 14
easy の意味 easy (= ease + -y) < aise/eise < adjacens ラテン語 adjacens (cf. 🇬🇧 adjacent) 原義: 「近くにある」「隣接した」 「身近な」(物理的に近い)「親しみがある」(自分 の理解に近い)「易しい」(できることに近い) 主観的/相対的な概念: 利用者からの(広義の)近さ 対義語: hard 原義: 「強い」「手ごわい」 ※ easy とは無関係 15
4. simple と easy の関係 16
と easy の二者択一ではない simple/complex, easy/hard の直交した2つの評価軸 単純なトレードオフの関係にはない simple AND easy も complex AND hard もある 「 easy よりも simple を選ぼう」 ではない complex になりうるものを避けて simple を追求 しようというのがRich Hickeyの主張 選択するのは simple OR complex であって simple OR easy ではない simple AND easy は十分に実現可能 simple 17
構図例: "easy but complex" vs "simple but hard" ease を優先し complexity (↔ simplicity)を甘受する 短期: easy なため生産性が高く、 complex である ことも直ちに支障をきたさない 中長期: complex ゆえに生産性が急速に低下 構造的な限界により徐々に手に負えなくなる ⭐️ simplicity を優先し hardness (↔ ease)を甘受する 短期: hard ゆえに生産性が低く、 simple なもの を課題に適用するにはいくらか時間が掛かる 中長期: simple なため生産性が高い水準を維持 hard から easy へと習熟/環境整備も進む 18
よくある誤解/派生解釈と🐬の見解(1) "Simple Made Easy"というRich Hickey による標語がある 「 simple 簡単解説」というのが文字通りの解釈 simple と easy の峻別という本題に関わる最重要の キーワードが見事に組み込まれた表現 しかし、タイトル自体に何かを促すメッセージ性が あるとは読み取りがたい 19
よくある誤解/派生解釈と🐬の見解(2) simple: 覚えることの少なさ重視 easy: 手数の少なさ重視 simplicity と ease がもたらしうる実用的メリットを 分かりやすく伝えようという試みに感じられる しかし、 simplicity が客観的な構造の問題から主観 的な体験の問題に変質してしまう危うさがある 「覚えることが少ない」という体験はむしろ easy であることの例と位置付けるのが素直そう 20
よくある誤解/派生解釈と🐬の見解(3) simple と easy はトレードオフなので simple を選ぼう simple にすると ease が損なわれ、 easy にすると simplicity が損なわれるだろうか? 確かに、 simple but hard なもの、 easy but complex なものは両極端で分かりやすい対比 しかし、「設計対象の構造の単純さ」と「利用者 からの(広義の)近さ」というまったく異なる性質 の間に不可避的な連動関係があるとは考えがたい 21
誤解/派生解釈例に共通する傾向(🐬のメタ読み) simplicity を分かりやすく(easy に)理解しようとす るあまり、 simplicity が何かと complect している 例1: (例えば) simple にすると easy になるという 論理関係が加わっている 例2: simplicity に主観的な要素が加わっている 例3: simple/complex, easy/hard という独立した 評価軸が単一軸の二項対立にまとまっている 22
5. なぜ simplicity を重視するのか 23
人間には限界がある 理解することなく信頼できるものは作れない 一度にごくわずかな数のことしかできない 絡まったものは一緒に考えるしかない 複雑さ(complexity)は理解を損なわせる ⇒ いわゆる認知負荷(cognitive load)による制約 24
にするメリット 構造的に(必然的に) — simplicity の内在的性質 組み合わせやすい(composable) 独立性が高い(modular) 人間的に(結果的に) — 派生的な ease への好影響 理解しやすい 変更しやすい デバッグしやすい 柔軟 あとから方針/決定を見直すことも容易 置き換えられる simple 25
6. どのように simple にするのか 26
なものを見極める をもたらす(complect している)もの を避ける もともと simple なものを利用する 抽象化する(abstract) abstractの原義は「引き離す」(draw away) 詳細を覆い隠すことではない who, what, when, where, why, howをそれぞれ 検討することがヒントになるかも あらかじめ問題を simple にする(simplify) simple complexity 27
に見る simplicity 7. Clojure 28
すべて丸括弧ではなく複数の括弧を使い分ける 以前からある の例 ;; Common Lisp: Clojure Lisp (defun fizzbuzz (n) (let ((fizzp (zerop (mod n 3))) (buzzp (zerop (mod n 5)))) (cond ((and fizzp buzzp) "Fizz Buzz") (buzzp "Buzz") (fizzp "Fizz") (t n)))) 丸括弧が複数の役割を担って complect している as code: オペレーター呼び出し 束縛フォーム cond の節など、特殊形式/マクロの要素 as data: コンスセル(によるリスト/alist/plistなど) 29
;; Clojure (defn fizzbuzz [n] (let [fizz? (zero? (mod n 3)) buzz? (zero? (mod n 5))] (cond (and fizz? buzz?) "Fizz Buzz" buzz? "Buzz" fizz? "Fizz" :else n))) 括弧を役割ごとに使い分けたほうが simple ( ): オペレーター呼び出し(as code)、リスト(as data) [ ]: 束縛フォーム(as code)、ベクター(as data) { }: メタデータ(as code)、マップ(as data) ℹ️ Common Lispでもリーダーマクロによって括弧 の意味付けの変更は可能 30
オブジェクトよりも値 オブジェクト指向言語の例 // Scala: case class Coffee(price: Double): def applyTax(rate: Double): Coffee = copy(price = price * (1 + rate)) オブジェクト(クラス)に以下が complect している 値(value): それ自体としては不変のデータ [ミュータブルな場合] 状態(state): アイデンティ ティに紐付く値が時とともに変化するもの [メソッドを持つ場合] 関数: オブジェクトの文脈 でのクロージャー 名前空間/モジュール: 定義を束ねるもの 31
;; Clojure
;; (require '[lagenorhynque.cafe.coffee :as-alias coffee])
(defn make-coffee [price]
#::coffee{:price price})
(defn apply-tax [coffee rate]
(update coffee ::coffee/price * (+ 1 rate)))
では構造的に分離されていて simple
値
ただの不変のデータ
状態 を扱いたい場合] 次節で紹介 💁♂️
関数 ただのトップレベル関数
名前空間 モジュール: ns として独立
ℹ️ の拡張メソッドにより(メソッドとしての)
関数の分離は部分的に可能
Clojure
(value):
[
(state)
:
/
Scala
32
変数よりも管理された参照型 可変の 変数を持つ言語の例 変数を宣言 初期化 変数に再代入 変数を参照 // Scala: ( ) def heavyCalculation(xs: List[Int]): Int = var result = 0 // / for x <- xs do result += x * x // result // 可変の)変数に以下が complect している アイデンティティ: 値が変化しても変わらない同 一の実体 値: 変数に紐付いているデータ 時間: 再代入のたびに生じるアイデンティティと 値の紐付き関係の遷移 ( 33
;; Clojure (defn heavy-calculation [xs] (let [result (volatile! 0)] (doseq [x xs] (vswap! result + (* x x))) @result)) 初期値を指定して参照型を導入 ; 参照型の値を更新(差し替え) ; 参照型の値を参照 ; 参照型では構造的に分離されていて simple アイデンティティ: 参照型そのもの 値: 参照型が保持するデータ 時間: 更新操作のたびに生じるアイデンティティ と値の関係の遷移 ⚠️ 並行処理向けには atom (CAS), ref (STM), etc. ℹ️ Scalaのサードパーティライブラリには Ref など 参照型を提供するものがある 34
継承よりもアドホック多相的な仕組み 継承を備えている オブジェクト指向言語の例 インターフェースの定義 // Scala: ( ) // trait Shape: def area: Double // ( ) class Rectangle(width: Double, height: Double) extends Shape: def area = width * height class Circle(radius: Double) extends Shape: def area = scala.math.Pi * radius * radius クラス 型 の定義とともにインターフェースの実装 サブタイピング(サブタイプ多相)により、継承関係 にある複数の型/クラス同士が complect している 35
;; Clojure ;; (defprotocol Shape (area [this])) ;; (defrecord Rectangle [width height]) (defrecord Circle [radius]) ;; (extend-protocol Shape Rectangle (area [{:keys [width height]}] (* width height)) Circle (area [{:keys [radius]}] (* Math/PI radius radius))) インターフェースの定義 データ型の定義 インターフェースの実装 のプロトコルではデータ型定義とインター フェース実装が分離可能で simple Expression Problemへの解答例でもある ℹ️ Scalaにも型クラスというアドホック多相機構が ある Clojure 36
パターンマッチングよりもアドホック多相的な仕組み パターンマッチングを多用する言語の例 関数定義とともに引数でパターンマッチ # Elixir: defmodule Geometry do # def area(%{type: :rectangle, width: w, height: h}), do: w * h def area(%{type: :circle, radius: r}), do: :math.pi() * r * r end パターンマッチングではパターン(who)と対応する 振る舞い(what)のペアが複数 complect している 37
;; Clojure ;; (defmulti area :type) ;; (defmethod area :rectangle [{:keys [width height]}] (* width height)) (defmethod area :circle [{:keys [radius]}] (* Math/PI radius radius)) ディスパッチ関数 ディスパッチする値ごとのメソッド実装 のマルチメソッドではディスパッチ関数 とメソッド実装(what)が分かれていて simple ℹ️ にもClojure類似のプロトコルがある Clojure (who) Elixir 38
アクターよりもキュー 並行処理機構にアクターモデルを採用する言語の例 メッセージを受信するプロセス # Elixir: # pid = spawn(fn -> receive do msg -> IO.puts(msg) end end) プロセスへメッセージを送信 # send(pid, "hello") アクターではメッセージに対する振る舞い(what)と メッセージを送受信するプロセス(who)が complect している 39
;; Clojure
(require '[clojure.core.async :refer [<! >! chan go]])
チャネル ブロッキングキュー
;;
/
(def ch (chan))
軽量スレッドでチャネルへ値を送信
軽量スレッドでチャネルから値を受信
;;
(go (>! ch "hello"))
;;
(go (println (<! ch)))
では軽量スレッドでの振る舞い(what)と
値を送受信するチャネル(who)が分かれていて
core.async
simple
40
型システムではなくデータ仕様記述ライブラリの追加 clojure.spec: データ仕様を述語で記述する一種の コントラクトシステム metosin/malli: データ駆動のスキーマライブラリ cf. Typed Clojure: Clojureに型システムを追加する ライブラリ 🐬< データとスキーマを分けて扱うアプローチが simple 41
プラグインではなくデータ主体のCLI/ビルドツール Clojure CLI: deps.edn の中身はただのデータ tools.build: build.clj の中身はただの関数 cf. Leiningen: の中身は(マクロを含む)コード JavaのMavenの系譜のビルドツール プラグイン拡張モデル 🐬< 設定(データ)とビルドロジック(関数)が分かれて いて simple project.clj 42
破壊的変更を避けた積み重ねによる進化 Clojureエコシステム: 言語本体: 2009年(v1.0)から2026年(v1.12)現在に 至るまで破壊的変更のない積み重ね 標準/サードパーティライブラリ: 同様の安定進化 cf. Scalaエコシステム: 破壊を伴うイノベーション 🐬< simple な構造を吟味しながら組み合わせて破壊 なく進化させていく文化 43
と のコードベースの変遷 Clojure Scala で示される、 と のコードベースの進化の違い 🐬 も述べるように良し悪しは一概に 言えないが、コミュニティの価値観が表れている A History of Clojure (HOPL IV, 2020) Clojure Scala < Rich Hickey 44
と easy の区別の より抽象的(メタ)な示唆 8. simple 45
改めて simple と easy の根本的な違いとは "Simple Made Easy"の核心: simple ≠ easy simple である(simplicity) 設計対象の構造の単純さ 客観的な概念 easy である(ease) 利用者からの(広義の)近さ 主観的/相対的な概念 ⇒ Clojureエコシステム/コミュニティは simplicity を 追求して長期にわたり安定進化してきた 46
と ease の対比をさらに抽象化してみると simplicity → 対象/客体(object)・モノの構造 ease → 主体(subject)・ヒトの対象との関わり方 学習/経験や環境など、個人/社会の対象との向き 合い方 simplicity と ease を区別し simplicity を優先する → モノへの投資とヒトへの投資を区別する ヒトが移り変わっても残るモノには最初に意識的 に投資する simplicity 47
長く残るモノと移り変わるヒトから連想する古い格言 ars longa, vita brevis 🇬🇧: Art is long, life is short/brief. 🇯🇵: 技芸は長く、人生は短い。 古希語(原典): ὁ βίος βραχύς, ἡ δὲ τέχνη μακρή 原文での趣旨: 人生は短いのに対して(医療)技術の 道は長い(だから時間を無駄にせず学ばなければ)。 後世の意味の変化: (芸術家の)人生は短く儚いが、 芸術は長く残る。 48
技芸(ars)を磨きながら人生(vita)を高める多様な道 言語/エコシステムとコミュニティの選択 Clojure: simplicity を追求しながら ease を高める 他のLisp (e.g. Common Lisp) 他のJVM言語(e.g. Scala) 他の関数型言語(e.g. Scala, Elixir) ソフトウェア開発者として、さらには人として いかなる技芸を学び磨き上げ、何を残せるだろう 自分と社会のより良い体験/人生に向けて、何が できるだろう 49
simplicity とは何かを知るために を一通り観てみる の背景を探ってみる: A History of Clojure エコシステム コミュニティに触れてみる "Simple Made Easy" Clojure Clojure / 50
user> (-> (simple-made-easy-made-easy) revisit deepen extend) "Simple Made Easy" Made Easier ;; simplicity という長く続く価値を、皆さんにとってより身近に 51
Further Reading Simple Made Easy matthiasn/talk-transcripts > Hickey_Rich/SimpleMadeEasy.md Clojure Simple Made Easy Simplicity Matters · eed3si9n A History of Clojure Rich Already Answered That! Clojurian simple JVM Flix —— と「 シンプルさの必要性 」 紙箱 が出会った 志向な 関数型言語 ファーストインプレッション 52