Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scala絵文字ライブラリに Macroなどを導入してみた

Avatar for Shunsuke Tadokoro Shunsuke Tadokoro
August 01, 2017
1.3k

Scala絵文字ライブラリに Macroなどを導入してみた

Avatar for Shunsuke Tadokoro

Shunsuke Tadokoro

August 01, 2017
Tweet

More Decks by Shunsuke Tadokoro

Transcript

  1. ా ॴ  ॣ ༎  ! U P E

    P L S  w ݕ ࡧ Τ ϯ δ ϯ ࣄ ۀ ຊ ෦  Ϋ ϩ ʔ ϥ ʔ ։ ൃ  w ࢓ ࣄ Ͱ ͸ 4 D B M B  + B W B 4 D S J Q U  1 Z U I P O  w ϓ ϥ Πϕ ʔ τ Ͱ ͸ $ M P K V S F  $ M P K V S F 4 D S J Q U  w ࣾ ಺ Ͱ ͸ ʮ จ ࣈ ί ʔ υ ͷ ਓ ʯ ͱ ͔ 
 ʮ ΤϞ δ χ Ξ ʯ ͱ ݺ ͹ Εͯ ͍ · ͢
  2. ా ॴ  ॣ ༎  ! U P E

    P L S  w ݕ ࡧ Τ ϯ δ ϯ ࣄ ۀ ຊ ෦  Ϋ ϩ ʔ ϥ ʔ ։ ൃ  w ࢓ ࣄ Ͱ ͸ 4 D B M B  + B W B 4 D S J Q U  1 Z U I P O  w ϓ ϥ Πϕ ʔ τ Ͱ ͸ $ M P K V S F  $ M P K V S F 4 D S J Q U  w ࣾ ಺ Ͱ ͸ ʮ จ ࣈ ί ʔ υ ͷ ਓ ʯ ͱ ͔ 
 ʮ ΤϞ δ χ Ξ ʯ ͱ ݺ ͹ Εͯ ͍ · ͢
  3. ా ॴ  ॣ ༎  ! U P E

    P L S  w ݕ ࡧ Τ ϯ δ ϯ ࣄ ۀ ຊ ෦  Ϋ ϩ ʔ ϥ ʔ ։ ൃ  w ࢓ ࣄ Ͱ ͸ 4 D B M B  + B W B 4 D S J Q U  1 Z U I P O  w ϓ ϥ Πϕ ʔ τ Ͱ ͸ $ M P K V S F  $ M P K V S F 4 D S J Q U  w ࣾ ಺ Ͱ ͸ ʮ จ ࣈ ί ʔ υ ͷ ਓ ʯ ͱ ͔ 
 ʮ ΤϞ δ χ Ξ ʯ ͱ ݺ ͹ Εͯ ͍ · ͢
  4. Ϟνϕʔγϣϯ w .BDͷֆจࣈΩʔϘʔυ͸࢖͍উख͕ྑ͍ w $NE $USM 4QBDF w ͕͔ͩ͠͠ʜ w

    6OJDPEFͷΞοϓσʔτʹ௥͍͍͍ͭͯͳ͍ w ͳͷͰɹɹͳͲ͕࢖͑ͳ͍ w ϓϥΠϕʔτͷϚγϯ͕.BD͡Όͳ͍
  5. Ϟνϕʔγϣϯ w .BDͷֆจࣈΩʔϘʔυ͸࢖͍উख͕ྑ͍ w $NE $USM 4QBDF w ͕͔ͩ͠͠ʜ w

    6OJDPEFͷΞοϓσʔτʹ௥͍͍͍ͭͯͳ͍ w ͳͷͰɹɹͳͲ͕࢖͑ͳ͍ w ϓϥΠϕʔτͷϚγϯ͕.BD͡Όͳ͍
  6. Ϟνϕʔγϣϯ w .BDͷֆจࣈΩʔϘʔυ͸࢖͍উख͕ྑ͍ w $NE $USM 4QBDF w ͕͔ͩ͠͠ʜ w

    6OJDPEFͷΞοϓσʔτʹ௥͍͍͍ͭͯͳ͍ w ͳͷͰɹɹͳͲ͕࢖͑ͳ͍ w ϓϥΠϕʔτͷϚγϯ͕.BD͡Όͳ͍
  7. Ϟνϕʔγϣϯ w .BDͷֆจࣈΩʔϘʔυ͸࢖͍উख͕ྑ͍ w $NE $USM 4QBDF w ͕͔ͩ͠͠ʜ w

    6OJDPEFͷΞοϓσʔτʹ௥͍͍͍ͭͯͳ͍ w ͳͷͰɹɹͳͲ͕࢖͑ͳ͍ w ϓϥΠϕʔτͷϚγϯ͕.BD͡Όͳ͍
  8. Ϟνϕʔγϣϯ w .BDͷֆจࣈΩʔϘʔυ͸࢖͍উख͕ྑ͍ w $NE $USM 4QBDF w ͕͔ͩ͠͠ʜ w

    6OJDPEFͷΞοϓσʔτʹ௥͍͍͍ͭͯͳ͍ w ͳͷͰɹɹͳͲ͕࢖͑ͳ͍ w ϓϥΠϕʔτͷϚγϯ͕.BD͡Όͳ͍
  9. Ϟνϕʔγϣϯ w .BDͷֆจࣈΩʔϘʔυ͸࢖͍উख͕ྑ͍ w $NE $USM 4QBDF w ͕͔ͩ͠͠ʜ w

    6OJDPEFͷΞοϓσʔτʹ௥͍͍͍ͭͯͳ͍ w ͳͷͰɹɹͳͲ͕࢖͑ͳ͍ w ϓϥΠϕʔτͷϚγϯ͕.BD͡Όͳ͍
  10. Ϟνϕʔγϣϯ w .BDͷֆจࣈΩʔϘʔυ͸࢖͍উख͕ྑ͍ w $NE $USM 4QBDF w ͕͔ͩ͠͠ʜ w

    6OJDPEFͷΞοϓσʔτʹ௥͍͍͍ͭͯͳ͍ w ͳͷͰɹɹͳͲ͕࢖͑ͳ͍ w ϓϥΠϕʔτͷϚγϯ͕.BD͡Όͳ͍
  11. Ϟνϕʔγϣϯ (JUIVCϥΠΫʹKPZͳͲͱॻ͚ΔΑ͏ʹ͍ͨ͠
 ˠFNPKJKBWBͷར༻ String str = ":grinning:awesome :wink:emojis!"; String result

    = EmojiParser.parseToUnicode(str); System.out.println(result); // "awesome emojis!" ͜ΕΛΑΓ4DBMBΒ͍͠ํ๏Ͱʂ
  12. *NQMJDJU$POWFSTJPO֓ཁ &OSJDI.Z-JCSBSZύλʔϯͰ
 طଘΫϥεʹϝιουΛ௥Ճ͢ΔʢΑ͏ʹݟ͔͚ͤΔʣ // Implicit ClassʹΑΔEnrich My Libraryύλʔϯ implicit class

    RichString(s: String) { def withSmile = s + ":)" } // new RichString("hello").withSmile "hello".withSmile // "hello:)" ˠ%&.0
  13. *NQMJDJU$POWFSTJPO࣮૷ ͜ΕΛ&NPKJQPMBUJPOʹԠ༻͢Δ object Emojipolation { implicit class EmojizableString(s: String) {

    def toEmoji: String = EmojiParser.parseToUnicode(s) } } // ར༻ଆ import io.github.todokr.Emojipolation._ "Hello! :joy:".toEmoji // Hello!
  14. 4USJOH*OUFSQPMBUJPO֓ཁ w Tิؒࢠม਺Λల։
 
 
 
 w Gิؒࢠ'PSNBUUFSͰ੔ܗ val name

    = "todokr" s"Hello, $name" // "Hello, todokr" val Pi: Double = 3.14159265359 f"Pi is $Pi%1.2f" // "Pi is 3.14"
  15. 4USJOH*OUFSQPMBUJPO࣮૷ ࣮૷ଆ object Emojipolation { implicit class EmojiImpl(val sc: StringContext)

    extends AnyVal { def emoji(args: Any*): String = { // Ճ޻จࣈϦςϥϧͷจࣈྻ෦෼͸
 // StringContextͷparts:Seq[String]ͱͯ͠ఏڙ͞ΕΔ // ࠓճ͸ศٓతʹઌ಄͚ͩΛѻ͏ val rawString = sc.parts.head // "Hello! :joy:" etc EmojiParser.parseToUnicode(rawString) } } } import io.github.todokr.Emojipolation._ emoji"Hello! :joy:" // Hello! ར༻ଆ
  16. .BDSP֓ཁ w ந৅ߏจ໦Λ૊Έସ͑ΔͨΊͷ࢓૊Έ w ந৅ߏจ໦ "45 ίʔυͷҙຯΛද͢໦ߏ଄ (pprint (macroexpand '(when

    (= color "blue") (println "Color is blue") (println "Not blue...")))) (if (= color "blue") (do (println "Color is blue") (println "Not blue..."))) ࢀߟDMPKVSFͷXIFOϚΫϩΛల։
  17. .BDSP֓ཁ"45ΛݟͯΈΔ // ϦϑϨΫγϣϯAPIͷΠϯϙʔτ import scala.reflect.runtime.universe._ // qิؒࢠͰߏจ໦Λੜ੒ val tree =

    q""" protected val x = 1 private val y = 3 x + y """ // ϦϑϨΫγϣϯAPIͷshowRawͰՃ޻લͷߏจ໦Λग़ྗ showRaw(tree)
  18. .BDSP֓ཁ"45ΛݟͯΈΔ ਤʹ͢Δͱ͜͏ #MPDL "QQMZ -JTU 7BM%FG 7BM%FG .PEJpFST .PEJpFST 5FSN/BNF

    5FSN/BNF -JUFSBM -JUFSBM $POTUBOU $POTUBOU 4FMFDU *EFOU -JTU 5FSN/BNF *EFOU 5FSN/BNF 5FSN/BNF Y 1305&$5&%  13*7"5& Z  Y QMVT Z
  19. .BDSP֓ཁ"45ͷ૸ࠪ w ύλʔϯϚονϯάΛ༻͍ͨ૸ࠪ w ؆୯ w యܕతͳͷ͸୯ҰͷϊʔυΞΫηε͢Δ৔߹ w 5SBWFSTFSͷαϒΫϥεΛ༻͍ͨ૸ࠪ w

    ߏจ໦શମΛ૸ࠪ͢Δ৔߹ Apply( // ࠓճͷՃ޻จࣈϦςϥϧʹϚον _, List( Apply( _, List( Literal(Constant(s: String)) ) ) ) )
  20. .BDSP࣮૷ object Emojipolation { // String Interpolationͷड෇෦ implicit class EmojipolationImpl(val

    sc: StringContext) extends AnyVal { def emoji(_: Any*): String = macro impl // ࣮૷͸ϚΫϩ } // ϚΫϩͷ࣮૷෦ def impl(c: blackbox.Context)(args: c.Expr[Any]*): c.Expr[String] = { import c.universe._ c.prefix.tree match { // String InterpolationͰड͚ͱͬͨStringʹϚον case Apply(_,List(Apply(_,List(Literal(Constant(s: String)))))) => // StringΛՃ޻͢Δߏจ໦ͱͯ͠ฦ͢ c.Expr[String](q"${EmojiParser.parseToUnicode(s)}") case _ => c.abort(c.enclosingPosition, "Oops!") } } }
  21. .BDSPϕϯνϚʔΫ Non Macro [info] Benchmark Mode Cnt Score Error Units


    [info] Main.listEmojis thrpt 30 3.454 ± 0.303 ops/s ֆจࣈϦςϥϧΛݸѻ͏ॲཧ
 KNISVOJXJGU
  22. .BDSPϕϯνϚʔΫ Non Macro [info] Benchmark Mode Cnt Score Error Units


    [info] Main.listEmojis thrpt 30 3.454 ± 0.303 ops/s Macro [info] Benchmark Mode Cnt Score Error Units
 [info] Main.listEmojis thrpt 30 337491.727 ± 3268.895 ops/s ֆจࣈϦςϥϧΛݸѻ͏ॲཧ
 KNISVOJXJGU
  23. .BDSPϕϯνϚʔΫ Non Macro [info] Benchmark Mode Cnt Score Error Units


    [info] Main.listEmojis thrpt 30 3.454 ± 0.303 ops/s Macro [info] Benchmark Mode Cnt Score Error Units
 [info] Main.listEmojis thrpt 30 337491.727 ± 3268.895 ops/s ˠεϧʔϓοτ͕໿ ഒʹ ֆจࣈϦςϥϧΛݸѻ͏ॲཧ
 KNISVOJXJGU
  24. ࢀߟࢿྉ w *NQMJDJU࠶ೖ໳!HBLV[[[[
 IUUQHBLV[[[[HJUIVCJPTMJEFTJNQMJDJU@SFJOUSPEVDUJPO w จࣈྻͷิؒ4DBMB%PDVNFOUBUJPO
 IUUQEPDTTDBMBMBOHPSHKBPWFSWJFXTDPSFTUSJOHJOUFSQPMBUJPOIUNM w ஋Ϋϥεͱ൚༻τϨΠτ4DBMB%PDVNFOUBUJPO
 IUUQEPDTTDBMBMBOHPSHKBPWFSWJFXTDPSFWBMVFDMBTTFTIUNM

    w EFGϚΫϩ4DBMB%PDVNFOUBUJPO
 IUUQEPDTTDBMBMBOHPSHKBPWFSWJFXTNBDSPTPWFSWJFXIUNM w 4DBMBͰίϯύΠϧ࣌ʹਖ਼نදݱΛνΣοΫ͢ΔʮϚΫϩ͔ͭ 4USJOH*OUFSQPMBUJPOʯ!YVXFJ
 IUUQYVXFJLIBUFOBCMPHDPNFOUSZ