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

Programming Language Spry

Programming Language Spry

93rd Smalltalk Study Meeting

TAKANO Mitsuhiro

October 28, 2016
Tweet

More Decks by TAKANO Mitsuhiro

Other Decks in Programming

Transcript

  1. S P RY 9 3 R D S M A

    L LTA L K S T U D Y M E E T I N G
  2. S P RY 
 P R O G R A

    M M I N G L A N G U A G E ୈ 9 3 ճ S M A L LTA L K ษ ڧ ձ @ S O R A B I T O I N C . 2 0 1 6 - 1 0 - 2 8 TA K A N O M I T S U H I R O A . K . A . @ TA K A N O 3 2
  3. ࠓ ೔ ͷ Ξ δΣ ϯ μ • ࣗݾ঺հ •

    Spry ͱ͸ • Nim ͱ͸ • Spry • ࣍ͷϖʔδ
  4. ࠓ ೔ ͷ Ξ δΣ ϯ μ ( C O

    N T. D ) • Spry • ֓ཁ • ಛ௃ • ಺෦ • Ϗϧυ • ίʔυྫ • จ๏ • Smalltalk ͱͷൺֱ
  5. ࣗ ݾ ঺ հ S E L F - I

    N T R O D U C T I O N
  6. ͓ લ ɺ ୭ Α • ߴ໺ޫ߂ • TAKANO Mitsuhiro

    • @takano32 • ॴଐ • SORABITO גࣜձࣾ • ٕज़εϖγϟϦετ • ೔ຊ UNIX Ϣʔβձ • װࣄ ͔ ཧࣄ
  7. ͓ લ ɺ ୭ Α • Smalltalk Developer • ࠷ۙ͸Πϯϑϥͷ੔උ͕த৺Ͱ͢

    • Ruby committer • ࠷ۙ͸͋·ΓίϛοτͰ͖͍ͯ·ͤΜ • ݴޠϚχΞ • ex. Rossetta Brainfuck
  8. S P RY ͷ ࡞ ऀ • Göran Krampe ͞Μ

    • झຯ • ιϑτ΢ΣΞ։ൃ • ϞʔλʔϘʔτ • 3DICC ͷ։ൃʹܞΘ͍ͬͯͨ • ಛʹ VR Ͱڠྗ࡞ۀ͢ΔͨΊͷ Terf ʹίϛοτ • ͦΕҎલ͸ 1994೥ ͔Β 2011೥·Ͱίϯαϧۀ
  9. ֤ ݴ ޠ ʹ ର ͢ Δ ॴ ײ •

    Smalltalk • Spry • Nim • Elixir
  10. S M A L LTA L K ͷ ࢥ ͍

    ग़ • 1994೥͝Ζʹ KTH Ͱ Smalltalk ͱग़ձ͏ • ͔ͨ͠ VisualWorks 1.0 Λ࢖͍ͬͯͨ • ࢥߟͷํ޲ੑͱίϛϡχςΟʹ΋ऒ͔Εͨ • 3DICC • Terf Ͱ͸ Squeak 4.x Λ࠾༻ • ಺෦ͰͷϢʔςΟϦςΟͳͲʹ͸ Pharo ΋࠾༻
  11. E L I X I R ʹ ࢥ ͏ ͱ

    ͜ Ζ • ୭͔ʹ Elixir Λ͍ͬͯ͡ΈΖͱݴΘΕͨ • Erlang ͷ VM - BEAM Ͱಈ͍͍ͯΔ • Erlang ͷϥΠϒϥϦ͕࢖͑Δ • Web ϑϨʔϜϫʔΫ Phoenix ͷීٴ͸͍͢͝ • Rails ΍ Node ͷ։ൃऀʹ޿͘ීٴ • ·ͩ Elixir ͰΞϓϦέʔγϣϯΛॻ͍ͨ͜ͱ͸ͳ͍
  12. N I M ʹ ͭ ͍ͯ ࢥ ͏ ͱ ͜

    Ζ • ࠷ۙ Nimrod ͱͯ͠΋஌ΒΕ͍ͯΔ Nim Λ஌ͬͨ • ϓϩάϥϛϯάݴޠͷ໺् • Smalltalk ʹ͸ٴ͹ͳ͍͕ϛχϚϦζϜͷݴޠ • Spry ͸ Nim Ͱ࡞ͬͨ • Nim ͕ಡΊͳ͍ͱத਎͕ಡΊͳ͍
  13. N I M $ brew info nim nim: stable 0.15.0

    (bottled), HEAD Statically typed, imperative programming language http://nim-lang.org/ /usr/local/Cellar/nim/0.15.0 (503 files, 24.4M) * Poured from bottle on 2016-10-25 at 17:44:09 From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/nim.rb
  14. A . 2 0 1 1 ೥ ຊ ֨ త

    ʹ ೔ ຊ ্ ཮
  15. 5 ෼ Ͱ ෼ ͔ Δ N I M •

    खଓ͖ܕ੩తܕ෇͚ • ଟ༷ͳಛ௃Λ࣋ͪ߹ΘͤΔ • खଓ͖ܕ • ΦϒδΣΫτࢦ޲ܕ • ؔ਺ܕ • δΣωϦοΫϓϩάϥϛϯά
  16. 5 ෼ Ͱ ෼ ͔ Δ N I M •

    ந৅ߏจ໦͋Γ • LISP ͔ΒӨڹ • ڧྗͳϚΫϩ • DSL Λ࡞੒͠΍͍͢ • ੩తܕ෇͚ͱಈతܕ෇͚ͷ͍͍ͱ͜औΓ • ίϯύΠϧ࣮ͯ͠ߦՄೳܗࣜͷϑΝΠϧΛੜ੒Մೳ • ΨϕʔδίϨΫγϣϯΛ౥ࡌ
  17. S P RY ͷ ֓ ཁ • Nim Ͱॻ͔Εͨ VM

    • C/C++ ΍ JavaScript ʹίϯύΠϧͰ͖Δ • ͞·͟·ͳݴޠͷಛ௃ΛऔΓೖΕ͍ͯΔ • Smalltalk, Rebol, Lisp, JavaScript, Forth, Nim
  18. S P RY ͷ ಛ ௃ F E A T

    U R E S O F S P RY
  19. S P RY ͷ ಛ ௃ - ެ ࣜ αΠ

    τ ͔ Β ͷ Ҿ ༻ • ϛχϚϦζϜͰಈతܕ෇͚ • ਅʹϗϞΠίχοΫ • ͢΂͕ͯ AST ͱͯ͠දݱ͞Ε͍ͯΔ • ૊ΈࠐΈͷΩʔϫʔυ͸ͳ͍ • ͢΂ͯͷॲཧ͸ؔ਺ʹׂΓ౰ͯͯߦ͏
  20. S P RY ͷ ಛ ௃ ( C O N

    T. D ) • Smalltalk ͷΑ͏ͳΩʔϫʔυҾ਺Λαϙʔτ • ܰྔͳແ໊ؔ਺ΛΫϩʔδϟʹΑ࣮ͬͯݱ • Smalltalk ͷΑ͏ʹ non local return ελΠϧ • C/C++ ΍ Nim ͷࢿ࢈Λੜ͔ͤΔ
  21. S P RY ͷ ಛ ௃ ( C O N

    T. D ) • Nim ͷ͍͍ͱ͜Ζ͕ͦͷ·· • εϨου͸ωΠςΟϒ • ΨϕʔδίϨΫγϣϯ͸ߴੑೳ • ϑοτϓϦϯτ͕খ͍͞ΠϯλϓϦλ • ελςΟοΫͳΠϯλϓϦλ͕ 100KB લޙͷαΠζ • Nim Ͱ͓Αͦ 2300ߦ
  22. N I M ͷ ಛ ௃ ( C O N

    T. D ) • ଟݴޠͱ਌࿨ੑ͕Α͍ • C/C++ ʹม׵Մೳ • JavaScript ʹม׵Մೳ • REPL Λ౥ࡌ • ispry ίϚϯυͰର࿩ • ΢ΣϒαΠτͰ΋ࢼͤΔ
  23. S P RY ͷ ಺ ෦ I N S I

    D E T H E S P RY
  24. Ͳ Ε͘ Β ͍ ਆ ͳ ͷ ͔ $ du

    -s * | sort -nr | head 6264 nimcache 1312 libui.a 1232 libuiosx.a 816 libui.dylib 784 ispry 752 spry 208 modules 96 spryvm.nim 64 ui.nim 16 controllgallery.nim
  25. 1 0 0 K B όΠφ Ϧ ͷ αΠ ζ

    ͔ ͱ ࢥ ͬ ͨ Β ι ʔε ί ʔ υ ͷ αΠ ζ ͩ ͬ ͨ
  26. S P RY ͷ Ϗ ϧ υ H O W

    T O B U I L D S P RY
  27. • ## Playing with it • 1. If you want

    to build the interpreter manually, go into `src` and run • `nim c -d:release spry` to build the Spry interpreter, or `nim c -d:release ispry` for the REPL. It should produce a single binary. • That's the standard invocation to build a nim program in release mode. • 2. Then go into samples and look at `hello.sy` as the next mandatory step :). • Its simply Spry source being run by the `spry` executable interpreter using the "shebang" trick.
  28. ΍ ͬͯ Έ ͨ $ nim c -d:release ispry Hint:

    used config file '/usr/local/Cellar/nim/0.14.2/nim/config/nim.cfg' [Conf] Hint: used config file '/Users/takano32/GitHub/spry/src/nim.cfg' [Conf] … Hint: spryoo [Processing] Hint: sprydebug [Processing] Hint: sprycompress [Processing] Users/takano32/GitHub/spry/src/modules/sprycompress.nim(1, 8) Error: cannot open 'lz4'
  29. L Z 4 ͕ ݟ ͭ ͔ Β ͳ ͍

    υ Ω ϡ ϝ ϯ τ ෆ උ Ͱ ͸ …
  30. ਖ਼ ղ • brew install lz4 • nimble install nimlz4

    • nim c -d:release spry • nim c -d:release ispry
  31. ί ʔ υ ྫ E X A M P L

    E O F S P RY C O D E
  32. ఆ ٛ 'to:do: = method [:to :block n = self

    [n <= to] whileTrue: [ do block n ..n = (n + 1)]]
  33. ఆ ٛ 'select: = method [:pred result = ([] clone)

    self reset [self end?] whileFalse: [ n = (self next) do pred n then: [result add: n]] ^result]
  34. ؆ ୯ ͳ ν ϡ ʔ τ Ϧ Ξϧ ΋

    ͋ Γ · ͢ I S P RY + T U T O R I A L 1 . S Y
  35. L A N G U A G E M A

    N U A L Α Γ ൈ ਮ
  36. L A N G U A G E M A

    N U A L • Comments • Literals • Words • Precedence • Booleans • Nil and Undef
  37. L A N G U A G E M A

    N U A L • Composities • Root • Functions and Methods • Scoping • Standard Library
  38. L I T E R A L S • Literal

    int • 340_000_000, 42, -34, +12 • Literal float • 3.14, 4e2, -2.734e-3, 40.00_001e2 • Literal string • “abc”, “hey \”there\””, “abc\x0Adef”
  39. W O R D S • ม਺ͷΑ͏ͳ΋ͷ • औಘʹ͸ $

    Λ࢖͏ • ධՁʹ͸Կ΋͚ͭͳ͍ • Ϧςϥϧͷ Word ͷهड़ʹ͸ ‘ • ͍͍ͩͨγϯϘϧͩͱࢥ͓͚ͬͯ͹Α͍
  40. P R E C E D E N C E

    • Smalltalk ͱಉ͡ • ࠨ͔ΒӈʹධՁ͕جຊ • ྫ֎Λॻ͖͍ͨͱ͖͸ؙׅހΛ࢖͏΂͠ x = (3 + 4) # Otherwise Spry assigns only 3 to x y = (2 + 3 * 4) # Equals 20 y = (2 + (3 * 4)) # Equals 14
  41. B O O L E A N S • true

    ͱ false ͱ͍͏ Word ͕ϧʔτͷ໊લۭؒʹଘࡏ x = true y = false x and y then: [echo "Both are not true"] x or y then: [echo "But one is true"] y not then: [echo "Y is not true"] y else: [echo "Y is not true"]
  42. N I L A N D U N D E

    F • ະఆٛͷม਺͸ undef • nil ͸Կ΋ͳ͍͜ͱΛද͢ • undef ͱ nil ͷҙຯ߹͍͸ҟͳΔ • ྆ํͱ΋ Word ͱͯ͠ଘࡏ͢Δͷ͸ಉ͡
  43. N I L A N D U N D E

    F echo x # prints "undef" echo (x ?) # prints "false" x = nil echo (x ?) # prints "true" echo x # prints "nil"
  44. C O M P O S I T E S

    - B L O C K • [ ͱ ] ͷΞϨ • do ؔ਺ͰධՁͰ͖Δ • ॻ͖׵͑Մೳ • ͳΜͯڪΖ͍͜͠ͱΛ… • Smalltalk ͷ OrderedCollection ʹ૬౰͢Δ
  45. C O M P O S I T E S

    - B L O C K # Evaluates to 3, try it in ispry do [1 + 2] # Evaluates to 7 foo = [1 + 2] foo at: 0 put: 5 do foo
  46. C O M P O S I T E S

    - PA R E N • ( ͱ ) • ධՁͷ༏ઌॱҐΛ੍ޚ • Block ͱಉ͡Α͏ʹධՁʹ΋࢖͑Δ • ݁Ռͷ஋͸࠷ޙͷࣜͱͳΔ
  47. C O M P O S I T E S

    - C U R LY • { ͱ } • ࿈૝഑ྻʹ࢖͏ map = {x = 50 y = 100} map at: ‘y # => 100
  48. C O M P O S I T E S

    - M A P • { ͱ } Λ࢖ͬͯ࡞ͬͨϠπ • Ωʔʹ͸ 11छྨͷ Word ͕࢖͑Δ • $foo, foo, :foo ͸۠ผ͞ΕΔ • ‘$foo ͱ ‘foo ΋ҟͳΔ
  49. R O O T • Smalltalk Ͱ͍͏ͱ͜Ζͷ Smalltalk Dictionary •

    Spry Ͱ͸ root ͱݺΜͰ͍Δ • ϞδϡʔϧͳͲ͸ root Ͱ͸ͳ໊͍લۭؒʹ഑ஔ
  50. F U N C T I O N S A

    N D M E T H O D S • Func • func ؔ਺Ͱ Block ͔Β࡞ͬͨϠπ • Func ͸ϒϩοΫ͕ධՁ͞ΕΔͱ͖ʹධՁ͞ΕΔ • ॻ͍ͯΔ͜ͱΑ͘෼͔Μͳ͍͚Ͳߴ֊ؔ਺͕࡞ΕΔͬΆ͍ • Methods • ϓϩτλΠϓͷΦϒδΣΫτࢦ޲ͬΆ͍͜ͱ͕Ͱ͖Δ • ϞδϡʔϧͷΠϯΫϧʔυʹࣅ͍ͯΔࣈ໘
  51. F U N C T I O N S #

    We create a func from a block and assign it to foo foo = func [3 + 4] # Now evaluating foo will give 7 foo # Call foo with no arguments foo # Call foo with one argument, an int foo 4 # Call foo with two arguments foo 4 “hey" # This func takes one argument and adds 4 to it foo = func [:x + 4] # Prints 9 on stdout echo foo 5
  52. F U N C T I O N S •

    Smalltalk ͷΑ͏ͳॻ͖ํ΋Ͱ͖Δ # This func takes one argument and adds 4 to it foo = func [:x x + 4] # Prints 9 on stdout echo foo 5 foo = func [:$x echo $x] bar = func [:x echo $x] x = "abc" bar x # prints "abc" foo x # prints "x" bar (3 + 4) # prints "7" foo (3 + 4) # prints "(3 + 4)"
  53. M E T H O D S • ϓϩτλΠϓͷΦϒδΣΫτࢦ޲ͩͱࢥ͑͹͍͍ #

    Call method foo on an int 4 foo # Call method foo on a string, with one more argument "hey" foo 7 # Call method foo with three arguments 4 foo "hey" “there" # Create a method that adds 5 to self plusfive = method [self + 5] echo (3 plusfive) # prints "8"
  54. M E T H O D S • ໊લ෇͖ΩʔϫʔυͰ΋ݺͿ͜ͱ͕Ͱ͖Δ #

    Create a function and assign it to a keyword add:to: = func [:x + :y] echo (add: 5 to: 6) # prints "11" # And a method in the same way add:and: = method [self + :x + :y] echo (3 add: 5 and: 6) # prints "14" # Can also be called like this echo (add:to: 5 6) # prints "11" echo (3 add:and: 5 6) # prints "14"
  55. S C O P I N G • είʔϓ͸ෳࡶ #

    Lookup in locals and outwards to root and all Modules listed in modules, undef if not found foo # Lookup outside this closure and outwards to root and all Modules listed in modules, undef if not found ..foo # Lookup in the Map called Bar, undef if not found Bar::foo # Lookup in self which is the nearest receiver Map @foo # Pull in the next argument to this Block invocation :foo
  56. S C O P I N G • ෳࡶ… #

    Bind in locals, regardless of any outer reachable foo's foo = 5 # Lookup outside this closure and outwards to root and all Modules listed in modules. # If found assign to that foo, otherwise bind in nearest outer closure. ..foo = 5 # Bind in the Map called Bar Bar::foo = 5 # Bind in self which is the nearest receiver Map @foo = 5
  57. S C O P I N G • ෳࡶ…… foo

    = func [ :a x = 10 a > 10 then: [x = 20] # This needs to say "..x = 20" ^x] echo foo 5 # prints 10 echo foo 12 # still prints 10! foo = func [ :a x = (a > 10 then: [20] else: [10]) ^x] echo foo 5 # prints 10 echo foo 12 # prints 20
  58. S TA N D A R D L I B

    R A RY • ଟ࠼ͳϥΠϒϥϦ • σβΠϯύλʔϯ • ϦϑϨΫγϣϯ • ࢛ଇԋࢉɾൺֱ • ͳͲͳͲ
  59. S TA N D A R D L I B

    R A RY • ૊ΈࠐΈͷϫʔυʹ͍ͭͯղઆ͞Ε͍ͯΔ • ࢖͍͜ͳ͢ʹ͸Ұ௨Γ͜ΕΛಡΉ΂͠ • ͪΐͬͱΫη͕͋Δ • ifTrue: ΑΓ΋୹͍ then: Ͱॻ͚ΔͥʢυϠΝ
  60. ͦ ͷ ଞ • Modules • ϑΝΠϧͳͲʹ෼͚ͯఆٛ • VM Modules

    • VM ͸ϚΠΫϩ • ඞཁͳϞδϡʔϧΛ௥Ճ • Spry grammer • BNF ͬΆ͍ͷ͕͋Δ • spryvm ͷਆ෦෼ʹهड़͞Ε͍ͯΔ
  61. S M A L LTA L K ͱ S P

    RY ͷ ൺ ֱ S M A L LTA L K A N D S P RY
  62. ! ?

  63. S M A L LTA L K ͱ ͷ ൺ

    ֱ • Smalltalk ͕ຬͨ͢ 10 ͷ৚݅ • 5 ͭʹ͍ͭͯ͸ຬ͍ͨͯ͠Δ • Spry ͸ Smalltalk ͱ͸ࣅͯඇͳΔݴޠ • “a Smalltalk” Ͱ͸ͳ͍͕ “Smalltalk-ish” • Smalltalk ͕ಘҙͰ͸ͳ͍෼໺Λૂ͍ͬͯΔʁʁʁ
  64. ॴ ײ • Spry ͸ Citrine ΑΓ͸ݴޠʹৄ͍͠ํ੍͕࡞ऀ • ࠷ॳ͔Β࣮૷ޙʹةዧ͞ΕΔ໰୊͸෷১͍ͯ͠Δ •

    Citrine ͷํ͕ Smalltalk ʹࣅ͍ͯΔ • Smalltalk ͷΑ͏ͳݴޠΛ໨తͱ͍ͯ͠ͳ͍
  65. TA K A N O M I T S U

    H I R O A . K . A . @ TA K A N O 3 2 ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠