SlideShare a Scribd company logo
JavaからScala、そしてClojureへ
実務で活きる関数型プログラミング
lagénorhynque 🐬カマイルカ
(defprofile lagénorhynque

:id @lagenorhynque

:readings ["/laʒenɔʁɛ̃
k/" "ラジェノランク"]

:aliases ["カマイルカ" "🐬"]

:languages [Java Japanese ; native languages

Clojure Haskell ; functional languages

English français] ; European languages

:interests [programming

language-learning

law politics

mathematics])
1. 私と仙台
2. 私と関数型言語
3. Opt Technologiesと関数型言語
4. 関数型プログラミングの実践例
5. 関数型プログラミング的な発想
私と仙台
プライベート
岐阜出身
2012年春〜: 東京
2022年春〜: 千葉
仙台/宮城/東北に接点は(たぶん)なさそう
が以前から気になっている🐬
仙台うみの杜水族館
仕事(オプト)
オプトの は主に仙台拠点で
開発運用されていた
2017年頃から東京の開発部門も関わり始める
そのタイミングで東京所属の私もジョイン
2018年には仙台拠点へ出張する機会も
2021年にフルリモートワーク前提で東京と仙台
の開発部門が統合された
現在も仙台在住のメンバーと日常的に一緒に仕事
している
広告運用支援ツール群
私と関数型言語
year event
2011 大学(法学部) 4年で初めてプログラミングに
少し触れる: SQL, Java
2012 前職の会社に新卒入社し、
Javaでの業務システム開発に携わり始める
2014 趣味で関数型言語に傾倒する:
Haskell, Clojure, Erlang, Scala, OCaml, etc.
2015 Clojure, Haskell, Scalaの勉強会に参加する
ようになり、のちの同僚とも出会う
year event
2016 オプトに中途入社し、
大規模なScala開発を経験する
2017 開発中のプロダクトの小さなバッチに
Clojureを社内初導入する
2018 新規プロダクトのREST API実装にClojureを
採用する
2019 新規プロダクトのGraphQL API実装に
Clojureを採用する
2021 開発チームを離れ、開発組織横断的な技術
マネジメント業務へ
発表:
at on 2017/01/28
JavaプログラマこそClojureを始めようという悪魔
の誘い😈
JavaからClojureへ
第十八回#渋谷java
発表:
at on 2019/07/25
オプトでのClojure採用から普及の歴史⚔️について
ジョーク成分多めに紹介
Clojurian Conquest
Shibuya.lisp lispmeetup #78
記事: Clojureをプロダクトに導入した話
記事: サービス間連携のためのGraphQL APIをClojure
で開発している話
Opt Technologiesと関数型言語
社内での関数型言語利用の歴史
発足(2016年)以前から前身とな
った開発会社でメイン開発言語だった
近年はバックエンド開発の利用言語が多様化して
いるが、引き続き主要言語のひとつ
2017年の導入からシェアが拡大し、重要なプロ
ダクトを支える言語のひとつになった
当初は一人しか経験者がいなかったが、継続的に
開発可能な体制に成熟してきた
Scala
Opt Technologies
Clojure
2018年頃に導入を試みたが、プロダクト開発が
諸事情により中止になり現存しない😇
開発者向け管理画面のために小さく使われている
例がある
上記HaskellプロダクトのWebフロントエンドに
も採用されていた
cf.
Haskell
Elm
Opt Technologiesの主な利用技術
関数型プログラミングの実践例
Java
オブジェクト指向・非関数型言語
静的型付き言語
JVM言語
関数型プログラミング関連機能が充実してきた
cf.
// メソッドの定義

jshell> void hello(Object x) {

...> System.out.println("Hello, %s!".formatted(x));

...> }

| created method hello(Object)

// メソッドの呼び出し

jshell> hello("Java")

Hello, Java!
jshell コマンド
Scala
オブジェクト指向・関数型言語
静的型付き言語
JVM言語
オブジェクト指向に関数型が溶け込んだ言語
cf.
// メソッドの定義

scala> def hello(x: Any): Unit =

| println(s"Hello, $x!")

|

def hello(x: Any): Unit

// メソッドの呼び出し

scala> hello("Scala")

Hello, Scala!
scala コマンド
Clojure
非オブジェクト指向・関数型言語
動的型付き言語
JVM言語
オブジェクト指向を嫌い関数型を志向したLisp
cf. +
;; 関数の定義

user=> (defn hello [x]

#_=> (println (str "Hello, " x "!")))

#'user/hello

;; 関数の呼び出し(適用)
user=> (hello "Clojure")

Hello, Clojure!

nil
clojure コマンド rebel-readline
とあるプロダクトのJavaコード(抜粋)
return mediaProcessLogDao.selectMediaProcessLogs(baseDate,

modifiedEntities).stream()

.map(this::normalizeTargetIndexIfAdvertise)

.collect(Collectors.groupingBy(MediaProcessLogEntity::getKey))
.entrySet().stream().collect(toMap(

Map.Entry::getKey,

group -> {

List<MediaProcessLogEntity> entities = group.getValue();

if (entities.stream()

.allMatch(MediaProcessLogEntity::isEmpty)) {

return true;

}

return entities.stream()

.filter(e -> !e.isEmpty())

.allMatch(MediaProcessLogEntity::isImported);

}));
問題を単純化すると
エンティティのリストをその要素のキーごとにグルー
ピングし、個々のグループの値が特定の条件を満たす
かどうかを表す対応表(マップ)がほしい。
どのようなプログラムに落とし込む?
Java: サンプルデータ
jshell> record Entity(int key, String x) {}

| created record Entity

jshell> final var entities = List.of(

...> new Entity(3, "a"),

...> new Entity(1, "b"),

...> new Entity(2, "c"),

...> new Entity(1, "d"),

...> new Entity(1, "e")

...> )

entities ==> [Entity[key=3, x=a], Entity[key=1, x=b],

Entity[k ... x=d], Entity[key=1, x=e]]
Java: 命令型(imperative)のアプローチ
jshell> final var keyToEntities =

...> new HashMap<Integer, List<Entity>>();

...> for (final var e : entities) {

...> final var es = keyToEntities.getOrDefault(e.key(),

...> new ArrayList<Entity>());

...> es.add(e);

...> keyToEntities.put(e.key(), es);

...> }

keyToEntities ==> {}

jshell> keyToEntities

keyToEntities ==> {1=[Entity[key=1, x=b], Entity[key=1, x=d],

Entity[key=1, x=e]], 2=[Entity[key=2, x=c]],

3=[Entity[key=3, x=a]]}
jshell> final var result = new HashMap<Integer, Boolean>();

...> for (final var entry : keyToEntities.entrySet()) {

...> result.put(entry.getKey(),

...> entry.getValue().size() > 1);

...> }

result ==> {}

jshell> result

result ==> {1=true, 2=false, 3=false}
Java: 関数型(functional)のアプローチ
※ REPLでの行継続のため行末に. を置いている
jshell> entities.stream().

...> collect(Collectors.groupingBy(Entity::key)).

...> entrySet().stream().

...> collect(Collectors.toMap(

...> Map.Entry::getKey,

...> group -> group.getValue().size() > 1

...> ))

$3 ==> {1=true, 2=false, 3=false}
Scala: サンプルデータ
scala> case class Entity(key: Int, x: String)

// defined case class Entity

scala> val entities = Seq(

| Entity(3, "a"),

| Entity(1, "b"),

| Entity(2, "c"),

| Entity(1, "d"),

| Entity(1, "e"),

| )

val entities: Seq[Entity] = List(Entity(3,a), Entity(1,b),

Entity(2,c), Entity(1,d), Entity(1,e))
Scala: 関数型(functional)のアプローチ
scala> entities.

| groupBy(_.key).

| view.

| mapValues(_.length > 1).

| toMap

val res0: Map[Int, Boolean] = Map(1 -> true, 2 -> false,

3 -> false)
Clojure: サンプルデータ
user=> (def entities [#:entity{:key 3

#_=> :x "a"}

#_=> #:entity{:key 1

#_=> :x "b"}

#_=> #:entity{:key 2

#_=> :x "c"}

#_=> #:entity{:key 1

#_=> :x "d"}

#_=> #:entity{:key 1

#_=> :x "e"}])

#'user/entities
Clojure: 関数型(functional)のアプローチ
user=> (update-vals (group-by :entity/key entities)

#_=> #(> (count %) 1))

{3 false, 1 true, 2 false}
考察: 命令型(imperative)のアプローチ
2種類の変数とfor文によるループ処理
変数やメソッドの命名、レイアウトなどの工夫を
しないとコードの意図が埋もれがち
文(statement)が登場し、命令(コマンド)の並びとし
て表現されている
マップやリストが破壊的に更新されている: 可変
(mutable)データ
変数への再代入を封じる(Javaではfinal を付ける)
だけでも安心感が高まる
考察: 関数型(functional)のアプローチ
リストをグルーピングし、マップの値を変換すると
いう意図が関数/メソッドで表されている
引数で振る舞いを指定している: 高階関数
(higher-order function)
与えているのは無名関数(anonymous function)/
ラムダ式(lambda expression)
cf. オブジェクト指向のStrategyパターン
関数型言語では汎用的で高機能な関数/メソッド
が標準で充実している
全体が式(expression)で構成され、データの変換と
して表現されている
今回の例では途中過程にローカル変数もない
関数型言語では簡潔に関数を組み合わせ加工する
手段が豊富に用意されている
コード上で更新される変数やデータは見当たらない
調べてみると初期化以降にデータが更新されてい
ないことが分かる: 不変(immutable)データ
関数型言語ではデフォルトで変数は再代入でき
ず、不変データを利用しやすくなっていることが
多い
関数型プログラミング的な発想
「イミュータビリティ」と「コンポーザビリティ」を
重視する
イミュータビリティ(immutability; 不変性)
形容詞形: イミュータブル(immutable; 不変)
対義語: ミュータビリティ(mutability; 可変性)、
ミュータブル(mutable; 可変)
もとのまま変化しない(させられない)性質
凍結するイメージ? 🧊
破壊的な更新操作(再代入、更新、削除)を提供せ
ず、作成(初期化)し、取得する(読み取る)ことに
徹する
主なメリット
可読性や変更容易性、コンポーザビリティが向上
しやすくなる
デバッグやテストも容易になる
並行プログラミング、分散システムと相性が良い
プログラミング言語に限らない例
イミュータブルインフラストラクチャ
台帳データベース、追記型のRDBテーブル設計
バージョン管理システム
コンポーザビリティ(composability; 合成可能性)
形容詞: コンポーザブル(composable; 合成可能)
要素同士が組み合わせられる性質
LEGOブロックのイメージ? 🧱
主なメリット
再利用性や拡張性が向上する
高凝集で疎結合な「モジュール」(ソフトウェア
コンポーネント)に繋がる
プログラミング言語に限らない例
Pipes & Filters
Ports & Adapters (ヘキサゴナルアーキテクチャ)
Single Responsibility Principle (SRP)
( によるプレゼン)
UNIX哲学
Simple Made Easy Rich Hickey
関数型プログラミングは楽しい😆
関数型言語は怖くない( JavaプログラマこそScalaや
Clojureを試してみよう! )。
思考のリソースを節約し、扱いやすいソフトウェアを
設計するために、その発想を活かそう。
Further Reading
コミュニティイベント
: Haskell
: Lisp系言語(Clojure, Common Lispな
ど)
: Elixir
: Scala
Haskell-jp
Shibuya.lisp
fukuoka.ex/kokura.ex/ElixirImp
rpscala
書籍
: Scala, Erlang, Clojure,
Haskell
cf. (原書続
編): Elixir, Elm, Idris
Scala
『7つの言語7つの世界』
Seven More Languages in Seven Weeks
『実践Scala入門』
『Scalaスケーラブルプログラミング第4版』
『Scala関数型デザイン&プログラミング』
Clojure
cf. (原書第3
版)
Haskell
『プログラミングClojure 第2版』
Programming Clojure, Third Edition
Getting Clojure
Clojure Applied
『[増補改訂]関数プログラミング実践入門』
『プログラミングHaskell 第2版』
『すごいHaskellたのしく学ぼう!』
『Haskell入門関数型プログラミング言語の基礎と
実践』
OCaml
Erlang
Elixir
『プログラミングの基礎』
『プログラミングin OCaml』
『プログラミングErlang』
『すごいErlangゆかいに学ぼう!』
『プログラミングElixir(第2版)』

More Related Content

What's hot (20)

PDF
Javaのログ出力: 道具と考え方
Taku Miyakawa
 
PDF
これから Haskell を書くにあたって
Tsuyoshi Matsudate
 
PDF
オブジェクト指向できていますか?
Moriharu Ohzu
 
PDF
オブジェクト指向プログラミングのためのモデリング入門
増田 亨
 
PDF
Dockerからcontainerdへの移行
Kohei Tokunaga
 
PPTX
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
Atsushi Nakamura
 
PDF
プログラミングコンテストでの動的計画法
Takuya Akiba
 
PDF
TRICK 2022 Results
mametter
 
PDF
ドメインオブジェクトの見つけ方・作り方・育て方
増田 亨
 
PDF
ドメイン駆動設計のための Spring の上手な使い方
増田 亨
 
PDF
Constexpr 中3女子テクニック
Genya Murakami
 
PPTX
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
NTT DATA Technology & Innovation
 
PDF
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
Takuto Wada
 
PDF
PlaySQLAlchemy: SQLAlchemy入門
泰 増田
 
PPT
メタプログラミングって何だろう
Kota Mizushima
 
PDF
Javaの進化にともなう運用性の向上はシステム設計にどういう変化をもたらすのか
Yoshitaka Kawashima
 
PDF
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
増田 亨
 
PPTX
C#とILとネイティブと
信之 岩永
 
PPTX
Gstreamer Basics
Seiji Hiraki
 
PDF
テスト文字列に「うんこ」と入れるな
Kentaro Matsui
 
Javaのログ出力: 道具と考え方
Taku Miyakawa
 
これから Haskell を書くにあたって
Tsuyoshi Matsudate
 
オブジェクト指向できていますか?
Moriharu Ohzu
 
オブジェクト指向プログラミングのためのモデリング入門
増田 亨
 
Dockerからcontainerdへの移行
Kohei Tokunaga
 
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
Atsushi Nakamura
 
プログラミングコンテストでの動的計画法
Takuya Akiba
 
TRICK 2022 Results
mametter
 
ドメインオブジェクトの見つけ方・作り方・育て方
増田 亨
 
ドメイン駆動設計のための Spring の上手な使い方
増田 亨
 
Constexpr 中3女子テクニック
Genya Murakami
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
NTT DATA Technology & Innovation
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
Takuto Wada
 
PlaySQLAlchemy: SQLAlchemy入門
泰 増田
 
メタプログラミングって何だろう
Kota Mizushima
 
Javaの進化にともなう運用性の向上はシステム設計にどういう変化をもたらすのか
Yoshitaka Kawashima
 
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
増田 亨
 
C#とILとネイティブと
信之 岩永
 
Gstreamer Basics
Seiji Hiraki
 
テスト文字列に「うんこ」と入れるな
Kentaro Matsui
 

Similar to JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング (20)

PDF
Scalaで萌える関数型プログラミング[1.1.RC1]
Ra Zon
 
PDF
Scalaで萌える関数型プログラミング[完全版]
Ra Zon
 
PDF
Scalaプログラミング・マニアックス
Tomoharu ASAMI
 
PDF
Object-Funcational Analysis and design
Tomoharu ASAMI
 
PDF
第2回関数型言語勉強会 大阪
Naoki Kitora
 
PDF
関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ
Kent Ohashi
 
PDF
From Scala/Clojure to Kotlin
Kent Ohashi
 
PDF
プログラミング言語Scala
TanUkkii
 
KEY
Clojure programming-chapter-2
Masao Kato
 
PDF
Clojureコレクションで探るimmutableでpersistentな世界
Kent Ohashi
 
PDF
磯野ー!関数型言語やろうぜー!
Ra Zon
 
PDF
オブジェクト指向開発におけるObject-Functional Programming
Tomoharu ASAMI
 
PDF
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
Kent Ohashi
 
ODP
Haskell
todorokit
 
PDF
Object-Functional Analysis and Design and Programming温泉
Tomoharu ASAMI
 
KEY
Beginners Scala in FAN 20121009
Taisuke Shiratori
 
PDF
Scalaで萌える関数型プログラミング[エッセンシャル版]
Ra Zon
 
PDF
実務者のためのかんたんScalaz
Tomoharu ASAMI
 
PPTX
ゼロから始めるScala文法 (再)
Suguru Hamazaki
 
PDF
渋谷JVM#1 Immutable時代のプログラミング言語 Clojure
Yoshitaka Kawashima
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Ra Zon
 
Scalaで萌える関数型プログラミング[完全版]
Ra Zon
 
Scalaプログラミング・マニアックス
Tomoharu ASAMI
 
Object-Funcational Analysis and design
Tomoharu ASAMI
 
第2回関数型言語勉強会 大阪
Naoki Kitora
 
関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ
Kent Ohashi
 
From Scala/Clojure to Kotlin
Kent Ohashi
 
プログラミング言語Scala
TanUkkii
 
Clojure programming-chapter-2
Masao Kato
 
Clojureコレクションで探るimmutableでpersistentな世界
Kent Ohashi
 
磯野ー!関数型言語やろうぜー!
Ra Zon
 
オブジェクト指向開発におけるObject-Functional Programming
Tomoharu ASAMI
 
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
Kent Ohashi
 
Haskell
todorokit
 
Object-Functional Analysis and Design and Programming温泉
Tomoharu ASAMI
 
Beginners Scala in FAN 20121009
Taisuke Shiratori
 
Scalaで萌える関数型プログラミング[エッセンシャル版]
Ra Zon
 
実務者のためのかんたんScalaz
Tomoharu ASAMI
 
ゼロから始めるScala文法 (再)
Suguru Hamazaki
 
渋谷JVM#1 Immutable時代のプログラミング言語 Clojure
Yoshitaka Kawashima
 
Ad

More from Kent Ohashi (20)

PDF
TDD with RDD: Clojure/LispのREPLで変わる開発体験
Kent Ohashi
 
PDF
🐬の推し本紹介2024: 『脱・日本語なまり 英語(+α)実践音声学』
Kent Ohashi
 
PDF
do Notation Equivalents in JVM languages: Scala, Kotlin, Clojure
Kent Ohashi
 
PDF
map関数の内部実装から探るJVM言語のコレクション: Scala, Kotlin, Clojureコレクションの基本的な設計を理解しよう
Kent Ohashi
 
PDF
Kotlin Meets Data-Oriented Programming: Kotlinで実践する「データ指向プログラミング」
Kent Ohashi
 
PDF
RDBでのツリー表現入門2024
Kent Ohashi
 
PDF
ミュータビリティとイミュータビリティの狭間: 関数型言語使いから見たKotlinコレクション
Kent Ohashi
 
PDF
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
Kent Ohashi
 
PDF
Team Geek Revisited
Kent Ohashi
 
PDF
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Kent Ohashi
 
PDF
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
Kent Ohashi
 
PDF
実用のための語源学入門
Kent Ohashi
 
PDF
メタプログラミング入門
Kent Ohashi
 
PDF
労働法の世界
Kent Ohashi
 
PDF
Clojureで作る"simple"なDSL
Kent Ohashi
 
PDF
RDBでのツリー表現入門
Kent Ohashi
 
PDF
GraphQL入門
Kent Ohashi
 
PDF
Everyday Life with clojure.spec
Kent Ohashi
 
PDF
たのしい多言語学習
Kent Ohashi
 
PDF
Ductモジュール入門
Kent Ohashi
 
TDD with RDD: Clojure/LispのREPLで変わる開発体験
Kent Ohashi
 
🐬の推し本紹介2024: 『脱・日本語なまり 英語(+α)実践音声学』
Kent Ohashi
 
do Notation Equivalents in JVM languages: Scala, Kotlin, Clojure
Kent Ohashi
 
map関数の内部実装から探るJVM言語のコレクション: Scala, Kotlin, Clojureコレクションの基本的な設計を理解しよう
Kent Ohashi
 
Kotlin Meets Data-Oriented Programming: Kotlinで実践する「データ指向プログラミング」
Kent Ohashi
 
RDBでのツリー表現入門2024
Kent Ohashi
 
ミュータビリティとイミュータビリティの狭間: 関数型言語使いから見たKotlinコレクション
Kent Ohashi
 
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
Kent Ohashi
 
Team Geek Revisited
Kent Ohashi
 
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Kent Ohashi
 
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
Kent Ohashi
 
実用のための語源学入門
Kent Ohashi
 
メタプログラミング入門
Kent Ohashi
 
労働法の世界
Kent Ohashi
 
Clojureで作る"simple"なDSL
Kent Ohashi
 
RDBでのツリー表現入門
Kent Ohashi
 
GraphQL入門
Kent Ohashi
 
Everyday Life with clojure.spec
Kent Ohashi
 
たのしい多言語学習
Kent Ohashi
 
Ductモジュール入門
Kent Ohashi
 
Ad

JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング