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
550
Onboarding Process for Scala Team
todokr
0
1.9k
Running Scala on AWS Lambda in a Snappy Way
todokr
7
4.6k
Scalaでつくる ちょっとしたCLIツール
todokr
0
1k
新しいプログラミング言語の学び方 HTTPサーバーを作って学ぶ Java, Scala, Clojure
todokr
28
20k
Scala絵文字ライブラリに Macroなどを導入してみた
todokr
0
1.5k
Clojureに入門してHTTPサーバーをつくってみた話
todokr
3
1.1k
emojiconに行ってきました
todokr
2
790
Scalaリファクタリング入門「大改造!静的ビフォー・アフター」
todokr
3
1.3k
Other Decks in Technology
See All in Technology
なぜ今、コスト最適化(倹約)が必要なのか? ~AWSでのコスト最適化の進め方「目的編」~
htan
1
110
M&A 後の統合をどう進めるか ─ ナレッジワーク × Poetics が実践した組織とシステムの融合
kworkdev
PRO
1
420
プロダクト成長を支える開発基盤とスケールに伴う課題
yuu26
4
1.3k
入社1ヶ月でデータパイプライン講座を作った話
waiwai2111
1
260
顧客の言葉を、そのまま信じない勇気
yamatai1212
1
350
AzureでのIaC - Bicep? Terraform? それ早く言ってよ会議
torumakabe
1
470
Frontier Agents (Kiro autonomous agent / AWS Security Agent / AWS DevOps Agent) の紹介
msysh
3
160
AWS Network Firewall Proxyを触ってみた
nagisa53
0
190
Context Engineeringの取り組み
nutslove
0
310
Embedded SREの終わりを設計する 「なんとなく」から計画的な自立支援へ
sansantech
PRO
3
2.3k
小さく始めるBCP ― 多プロダクト環境で始める最初の一歩
kekke_n
1
370
今日から始めるAmazon Bedrock AgentCore
har1101
4
400
Featured
See All Featured
Abbi's Birthday
coloredviolet
1
4.7k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
130
Site-Speed That Sticks
csswizardry
13
1.1k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
170
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.1k
Accessibility Awareness
sabderemane
0
51
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
57
50k
Building an army of robots
kneath
306
46k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
Technical Leadership for Architectural Decision Making
baasie
1
240
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
170
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