Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
わかる!Java to Clojure
Search
Shunsuke Tadokoro
October 05, 2017
Technology
6
1.8k
わかる!Java to Clojure
2017.10.4「教養としてのClojure」の発表資料です
Shunsuke Tadokoro
October 05, 2017
Tweet
Share
More Decks by Shunsuke Tadokoro
See All by Shunsuke Tadokoro
ある日「Webエンジニアなら、Webサーバーは作れますよね」と言われたら? ~ 3つのJVM言語で作って学ぶ
todokr
2
500
Onboarding Process for Scala Team
todokr
0
1.6k
Running Scala on AWS Lambda in a Snappy Way
todokr
7
4.2k
Scalaでつくる ちょっとしたCLIツール
todokr
0
890
新しいプログラミング言語の学び方 HTTPサーバーを作って学ぶ Java, Scala, Clojure
todokr
28
19k
Scala絵文字ライブラリに Macroなどを導入してみた
todokr
0
1.3k
Clojureに入門してHTTPサーバーをつくってみた話
todokr
3
1k
emojiconに行ってきました
todokr
2
710
Scalaリファクタリング入門「大改造!静的ビフォー・アフター」
todokr
3
1.2k
Other Decks in Technology
See All in Technology
OPENLOGI Company Profile
hr01
0
62k
自分の軸足を見つけろ
tsuemura
1
180
MCP Documentation Server @AI Coding Meetup #1
yyoshiki41
1
2.3k
ペアーズにおけるData Catalog導入の取り組み
hisamouna
0
260
PostgreSQL Unconference #52 pg_tde
nori_shinoda
1
250
AIエージェントの地上戦 〜開発計画と運用実践 / 2025/04/08 Findy W&Bミートアップ #19
smiyawaki0820
17
4.9k
ソフトウェア開発現代史: なぜ日本のソフトウェア開発は「滝」なのか?製造業の成功体験とのギャップ #jassttokyo
takabow
3
1.8k
「家族アルバム みてね」を支えるS3ライフサイクル戦略
fanglang
4
620
ウェブアクセシビリティとは
lycorptech_jp
PRO
0
350
10分でわかるfreeeのQA
freee
1
11k
Startups On Rails 2025 @ Tropical on Rails
irinanazarova
0
200
チームビルディング「脅威モデリング」ワークショップ
koheiyoshikawa
0
190
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
137
6.9k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
30
1.1k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
It's Worth the Effort
3n
184
28k
Speed Design
sergeychernyshev
28
870
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
Site-Speed That Sticks
csswizardry
4
470
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
4
510
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.4k
Transcript
Θ͔Δʂ+BWBUP$MPKVSF ڧཁڭཆͱͯ͠ͷ$MPKVSF EDMK !UPEPLS ָ͘͠
୭ͩ ాॴॣ༎!UPEPLS ීஈ4DBMBΤϯδχΞ ϓϥΠϕʔτͰ$MPKVSF$MPKVSF4DSJQUΛͪΐͪ͜ΐ͜৮Δॳ৺ऀ
None
͓͢͠Δ͜ͱ w 8IZ-JTQ 8IZ$MPKVSF w جຊతͳจ๏ʹ͍ͭͯ w +BWBͷΞϨΛ$MPKVSFͰॻ͍ͯΈΑ͏
8IZ-JTQ w େֶͰ৮͍ͬͯͨͷͰ w ࣄͷͨΊ w ʮܭࢉػϓϩάϥϜͷߏͱղऍʯΛಡΉͨΊ w &NBDTϢʔβʔͩͬͨͷͰ w
+BWB4DSJQU$ͷൽΛ͔Ϳͬͨ-JTQͩͱฉ͍ͯ w ϧϯό͕-JTQͰಈ͍͍ͯΔͱฉ͍ͯ w FUD
None
ϙʔϧɾάϨΞϜ 7JBXFCۀऀ :$PNCJOBUPSઃऀ
-JTQͰྑ͍ϓϩάϥϜ͕ॻ͚ΔͳΒɺ͏͖ͳΜͩɻ ͦ͏Ͱͳ͍ͳΒ͍͍ͬͨԿͷʹཱͭ ϙʔϧɾάϨΞϜ 7JBXFCۀऀ :$PNCJOBUPSઃऀ
ී௨ͷౕΒͷ্Λߦ͚ɻ -JTQͰྑ͍ϓϩάϥϜ͕ॻ͚ΔͳΒɺ͏͖ͳΜͩɻ ͦ͏Ͱͳ͍ͳΒ͍͍ͬͨԿͷʹཱͭ ϙʔϧɾάϨΞϜ 7JBXFCۀऀ :$PNCJOBUPSઃऀ
ී௨ͷౕΒͷ্Λߦ͚ɻ -JTQͰྑ͍ϓϩάϥϜ͕ॻ͚ΔͳΒɺ͏͖ͳΜͩɻ ͦ͏Ͱͳ͍ͳΒ͍͍ͬͨԿͷʹཱͭ ϙʔϧɾάϨΞϜ 7JBXFCۀऀ :$PNCJOBUPSઃऀ :BIPPʹച٫
ී௨ͷౕΒͷ্Λߦ͚ɻ -JTQͰྑ͍ϓϩάϥϜ͕ॻ͚ΔͳΒɺ͏͖ͳΜͩɻ ͦ͏Ͱͳ͍ͳΒ͍͍ͬͨԿͷʹཱͭ ϙʔϧɾάϨΞϜ 7JBXFCۀऀ :$PNCJOBUPSઃऀ Θͨ͠ ී௨ͷϓϩάϥϚ -JTQͰΣϒαʔϏεΛͭ͘Δͱ :BIPPʹԯԁͰങͬͯΒ͑Δʂʂʂ
:BIPPʹച٫
ͳͥ$PNNPO-JTQ4DIFNFͰͳ͘ $MPKVSFʁ
8IZ$MPKVSF w ಡΈ͢͞ w ׅހͷ͕গͳ͍ w ׅހͷछྨ͕ଟ͍ w #FUUFS+BWBͰ͋Δ͜ͱ w
ϦονɾώοΩʔ
8IZ$MPKVSF w ಡΈ͢͞ w ׅހͷ͕গͳ͍ w ׅހͷछྨ͕ଟ͍ w #FUUFS+BWBͰ͋Δ͜ͱ w
ϦονɾώοΩʔ
ಡΈ͢͞ $MPKVSF-JTQͷ౷ΛࣺͯɺಡΈ͢͞ΛͱͬͨʢΒ͍͠ʣ ͦͷͨΊɺ$PNNPO-JTQ4DIFNFʹൺͯ ɾׅހ͕গͳ͍ ɾׅހͷछྨ͕ଟ͍
ಡΈ͢͞ ͨͱ͑ؔͷҾ $PNNPO-JTQ 4DIFNF $MPKVSF (defun square (x) (* x
x)) (define (square x) (* x x)) (defn square [x] (* x x))
ಡΈ͢͞ ͨͱ͑BTTPDJBUJWFͳσʔλߏʢ+BWBͰ͍͏.BQʣ (defparameter greet '(("ja" . "͜Μʹͪ") ("en" . "hello")
("fr" . "bonjour")) (define greet '(("ja" "͜Μʹͪ") ("en" "hello") ("fr" "bonjour")) $PNNPO-JTQ 4DIFNF (def greet {"ja" "͜Μʹͪ" "en" "hello" "fr" "bonjour"}) $MPKVSF
8IZ$MPKVSF w ಡΈ͢͞ w ׅހͷ͕গͳ͍ w ׅހͷछྨ͕ଟ͍ w #FUUFS+BWBͰ͋Δ͜ͱ w
ϦονɾώοΩʔ
8IZ$MPKVSF w ಡΈ͢͞ w ׅހͷ͕গͳ͍ w ׅހͷछྨ͕ଟ͍ w #FUUFS+BWBͰ͋Δ͜ͱ w
ϦονɾώοΩʔ
#FUUFS+BWBͰ͋Δ͜ͱ (.concat "hello" " world") ; -> "hello world" ;;
"hello".concat(" world"); (.getName String) ; -> "java.lang.String" ; String.getName (.. user getAddress getCity) ; -> "Shibuya" ; user.getAddress().getCity(); (.-x (new java.awt.Point 2 3)) ;; 2 ;; -> new java.awt.Point(2, 3).x Math/PI ;; 3.141592653589793 ;; Math.PI +BWBͷ"1*͕ͦͷ··ݺͼग़ͤΔ☕️ ˠ+BWBͰͰ͖Δ͜ͱͰ͖Δʂͱ͍͏҆৺ײ
8IZ$MPKVSF w ಡΈ͢͞ w ׅހͷ͕গͳ͍ w ׅހͷछྨ͕ଟ͍ w #FUUFS+BWBͰ͋Δ͜ͱ w
ϦονɾώοΩʔ
8IZ$MPKVSF w ಡΈ͢͞ w ׅހͷ͕গͳ͍ w ׅހͷछྨ͕ଟ͍ w #FUUFS+BWBͰ͋Δ͜ͱ w
ͳʹΑΓָ͍͠ʂ
ͳʹΑΓָ͍͠ʂ w ߴ֊ؔԆධՁͳͲͷؔܕϓϩάϥϛϯάελΠϧ w ঢ়ଶʹ͍ͭͯͷߟ͑ํɺ*EFOUJUZ 4UBUF 7BMVFͷ w γϯϓϧ͞ʹ͍ͭͯ ͍Ζ͍Ζܹత
IUUQCPYPGQBQFSTIBUFOBCMPHDPNFOUSZTJNQMF@NBEF@FBTZ
ͭ·Γ$MPKVSF ͱ͖͍ͬͭ͢ʂ ֶͼָ͕͍͋ͬͯ͠ʂ
+BWBUP$MPKVSFͯ͠ΈΑ͏ w )FMMPXPSME w ࢛ଇԋࢉ w มએݴ w ؔએݴ w
ແ໊ؔ
खݩͰࢼ͢ͳΒ5SZ$MPKVSF͕͓͢͢Ί w 5SZ$MPKVSF IUUQXXXUSZDMKDPN
·ͣγϯλοΫεʹ׳ΕΑ͏ʂ
-JTQͷγϯλοΫε ׅހͷ࢝·Γ͔ΒऴΘΓ·Ͱ͕୯Ґ (ԿΒ͔ͷॲཧ ॲཧͷରͳͲ…)
͏׳Ε·ͨ͠Ͷ
)FMMPXPSME System.out.println("Hello world"); +BWB $MPKVSF
)FMMPXPSME System.out.println("Hello world"); +BWB (println "Hello world") $MPKVSF
࢛ଇԋࢉ 12 + 40 10 - 1 2 * 3
5 / 2 +BWB $MPKVSF
࢛ଇԋࢉ 12 + 40 10 - 1 2 * 3
5 / 2 +BWB (+ 12 40) (- 10 1) (* 2 3) (/ 5 2) $MPKVSF
࢛ଇԋࢉ 12 + 40 10 - 1 2 * 3
5 / 2 +BWB (+ 12 40) (- 10 1) (* 2 3) (/ 5 2) ; -> 5/2 Λѻ͏Ratioܕ $MPKVSF
˞จࣈྻͷ݁߹TUS จࣈྻͷ݁߹ Ͱͳ͘TUSΛ͏ (+ "hoge" "fuga") ClassCastException java.lang.String cannot be
cast to java.lang.Number clojure.lang.Numbers.add (Numbers.java:128) (str "hoge" "fuga") hogefuga
มએݴ int x = 10; +BWB $MPKVSF
มએݴ int x = 10; +BWB (def x 10) $MPKVSF
มએݴ MFUʹΑΔϩʔΧϧมఆٛʢϩʔΧϧଋറʣΛݟ͔͚Δ΄͏͕ଟ͍ (let [x 10] (+ x 3)) ; xletͷׅހ͚ͩͰࢀরͰ͖Δ
$MPKVSF
ؔએݴ public int f(int x) { return x + 1;
} +BWB $MPKVSF
ؔએݴ public int f(int x) { return x + 1;
} +BWB (defn f [x] (+ x 1)) $MPKVSF
ແ໊ؔ x -> x * 2 +BWB $MPKVSF
ແ໊ؔ x -> x * 2 +BWB (fn [x] (*
x 2)) $MPKVSF
ແ໊ؔ x -> x * 2 +BWB (fn [x] (*
x 2)) #(* % 2) ; ↑ͷ؆ܿͳه๏ $MPKVSF
ແ໊ؔΛͬͯΈΔ Arrays.asList(1, 2, 3).stream() .map(x -> x * 2) .collect(Collectors.toList());
// List(2, 4, 6) +BWB $MPKVSF
ແ໊ؔΛͬͯΈΔ Arrays.asList(1, 2, 3).stream() .map(x -> x * 2) .collect(Collectors.toList());
// List(2, 4, 6) +BWB (map (fn [x] (* x 2)) '(1 2 3)) $MPKVSF
ແ໊ؔΛͬͯΈΔ Arrays.asList(1, 2, 3).stream() .map(x -> x * 2) .collect(Collectors.toList());
// List(2, 4, 6) +BWB (map (fn [x] (* x 2)) '(1 2 3)) (map #(* % 2) '(1 2 3)) $MPKVSF
ͬͱ+BWBUP$MPKVSFͯ͠ΈΑ͏ w γʔέϯεͷจࣈྻ݁߹ w จࣈྻ͕ۭPSۭനจࣈ͔Ͳ͏͔ͷఆ w *OQVU4USFBN͔ΒจࣈྻΛͯ͢ಡΉ
γʔέϯεͷจࣈྻ݁߹
γʔέϯεͷจࣈྻ݁߹ String[] words = { "a", "b", "c" }; StringBuilder
sb = new StringBuilder(); for(String word : words) { sb.append(word); } System.out.println(sb.toString()); // "abc" // Java8 System.out.println(String.join("", words)); +BWBͷ߹
γʔέϯεͷจࣈྻ݁߹ (def words '("a" "b" "c")) (clojure.string/join "" words) ;
͘͠ (apply str words) DMPKVSFͷ߹
γʔέϯεͷจࣈྻ݁߹ (def words '("a" "b" "c")) (clojure.string/join "" words) ;
͘͠ (apply str words) DMPKVSFͷ߹
w ՄมҾΛड͚औΔؔʹγʔέϯεΛ͍ͨ͠ͱ͖ʹ͏ w +BWB4DSJQUͷBQQMZͱҰॹ BQQMZ (str ["a" "b" "c"]) ;
-> ["a" "b" "c"] (apply str ["a" "b" "c"]) ; -> abc ; (str "a" "b" "c") ͱಉ͡
γʔέϯεͷจࣈྻ݁߹ (def words '("a" "b" "c")) (clojure.string/join "" words) ;
͘͠ (apply str words) DMPKVSFͷ߹
จࣈྻ͕ۭPSۭനจࣈ͔Ͳ͏͔ͷఆ
จࣈྻ͕ۭPSۭനจࣈ͔Ͳ͏͔ͷఆ public static boolean isBlank(final CharSequence cs) { int strLen;
if (cs == null || (strLen = cs.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if (!Character.isWhitespace(cs.charAt(i))) { return false; } } return true; } isBlank("hello!"); // false isBlank(null); // true isBlank(""); // true isBlank("\r\n\t") // true +BWBͷ߹
จࣈྻ͕ۭPSۭനจࣈ͔Ͳ͏͔ͷఆ (defn blank? [s] (every? #(Character/isWhitespace %) s)) (blank? "helllo!")
; false (blank? nil) ; true (blank? "") ; true (blank? "\n\r\t") ; true DMPKVSFͷ߹
จࣈྻ͕ۭPSۭനจࣈ͔Ͳ͏͔ͷఆ (defn blank? [s] (every? #(Character/isWhitespace %) s)) (blank? "helllo!")
; false (blank? nil) ; true (blank? "") ; true (blank? "\n\r\t") ; true DMPKVSFͷ߹
FWFSZ w ίϨΫγϣϯͷશͯͷཁૉʹରͯ͠ ड़ޠؔʢCPPMFBOΛฦؔ͢ʣΛద༻ w શͯUSVFͳΒUSVF (every? even? '(2 4
6)) ; true (every? even? '(1 2 3)) ; false
จࣈྻ͕ۭPSۭനจࣈ͔Ͳ͏͔ͷఆ (defn blank? [s] (every? #(Character/isWhitespace %) s)) (blank? "helllo!")
; false (blank? nil) ; true (blank? "") ; true (blank? "\n\r\t") ; true DMPKVSFͷ߹
*OQVU4USFBN͔ΒจࣈྻΛͯ͢ಡΉ
*OQVU4USFBN͔ΒจࣈྻΛͯ͢ಡΉ try(BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream("./test.txt"))))
{ StringBuilder sb = new StringBuilder(); String line; while((line = reader.readLine()) != null) { sb.append(line); } System.out.println(sb.toString()); } +BWBͷ߹
*OQVU4USFBN͔ΒจࣈྻΛͯ͢ಡΉ (require [clojure.java.io :as io]) (with-open [bis (io/input-stream "./test.txt")] (println
(slurp bis))) $MPKVSFͷ߹
*OQVU4USFBN͔ΒจࣈྻΛͯ͢ಡΉ (require [clojure.java.io :as io]) (with-open [bis (io/input-stream "./test.txt")] (println
(slurp bis))) $MPKVSFͷ߹
DMPKVSFKBWBJPJOQVUTUSFBN w ҾͰड͚औͬͨ'JMF 63* 63- 4PDLFU CZUFྻ 4USJOHʢͰදݱ͞ΕͨύεʣΛ*OQVU4USFBNʹม w มޙͷ*OQVU4USFBNͷσϑΥϧτ࣮
KBWBJP#VGGFSFE*OQVU4USFBN (require '[clojure.java.io :as io]) (io/input-stream "http://example.com")
XJUIPQFO w +BWBͰ͍͏USZXJUISFTPVSDFߏจɺ 4DBMBͰ͍͏-PBO1BUUFSOΛ࣮ݱ͢Δͷ w XJUIPQFOͰPQFOͨ͠ϦιʔεউखʹDMPTF͞ΕΔ (with-open [in (io/input-stream "./test.txt")]
(do-something in)) ;; already closed!
TMVSQ w 3FBEFS #VGGFSFE3FBEFS *OQVU4USFBN 'JMF 63* 63- 4PDLFU
CZUFྻ DIBSྻΛड͚औΓɺ จࣈྻʹͯ͠ฦ͢ w ରʹͳΔॻ͖ग़͠ͷͨΊͷؔTQJU (spit "./test.txt" "hello I/O!") (println (slurp "./test.txt")) ;; -> hello I/O!
*OQVU4USFBN͔ΒจࣈྻΛͯ͢ಡΉ (require [clojure.java.io :as io]) (with-open [bis (io/input-stream "./test.txt")] (println
(slurp bis))) $MPKVSFͷ߹
*OQVU4USFBN͔ΒจࣈྻΛͯ͢ಡΉ (require [clojure.java.io :as io]) (with-open [bis (io/input-stream "./test.txt")] (println
(slurp bis))) $MPKVSFͷ߹ ;; όοϑΝϦϯάͤͣʹϑΝΠϧ͔ΒಡΉ͚ͩͳΒˣͰOK (println (slurp "./test.txt"))
ࠓ+BWBUP$MPKVSFͨ͠ͷ w )FMMPXPSME w ࢛ଇԋࢉ w มએݴ w ؔએݴ w
ແ໊ؔ w γʔέϯεͷจࣈྻ݁߹ w จࣈྻ͕ۭPSۭനจࣈ͔Ͳ͏͔ͷఆ w *OQVU4USFBN͔ΒจࣈྻΛͯ͢ಡΉ
None