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

Programming Language Spry

Programming Language Spry

93rd Smalltalk Study Meeting

Avatar for TAKANO Mitsuhiro

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 ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠