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
Slide 2
Slide 2 text
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
S M A L LTA L K ͷ ࢥ ͍ ग़
• 1994͝Ζʹ KTH Ͱ Smalltalk ͱग़ձ͏
• ͔ͨ͠ VisualWorks 1.0 Λ͍ͬͯͨ
• ࢥߟͷํੑͱίϛϡχςΟʹऒ͔Εͨ
• 3DICC
• Terf Ͱ Squeak 4.x Λ࠾༻
• ෦ͰͷϢʔςΟϦςΟͳͲʹ Pharo ࠾༻
Slide 15
Slide 15 text
E L I X I R ʹ ࢥ ͏ ͱ ͜ Ζ
• ୭͔ʹ Elixir Λ͍ͬͯ͡ΈΖͱݴΘΕͨ
• Erlang ͷ VM - BEAM Ͱಈ͍͍ͯΔ
• Erlang ͷϥΠϒϥϦ͕͑Δ
• Web ϑϨʔϜϫʔΫ Phoenix ͷීٴ͍͢͝
• Rails Node ͷ։ൃऀʹ͘ීٴ
• ·ͩ Elixir ͰΞϓϦέʔγϣϯΛॻ͍ͨ͜ͱͳ͍
Slide 16
Slide 16 text
N I M ʹ ͭ ͍ͯ ࢥ ͏ ͱ ͜ Ζ
• ࠷ۙ Nimrod ͱͯ͠ΒΕ͍ͯΔ Nim Λͬͨ
• ϓϩάϥϛϯάݴޠͷ्
• Smalltalk ʹٴͳ͍͕ϛχϚϦζϜͷݴޠ
• Spry Nim Ͱ࡞ͬͨ
• Nim ͕ಡΊͳ͍ͱத͕ಡΊͳ͍
Slide 17
Slide 17 text
N I M ? ? ?
N I M R O D ? ? ?
Slide 18
Slide 18 text
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
Slide 19
Slide 19 text
Q . ͭ͡ ༗ ໊ ͳ ݴ ޠ ʁ
Slide 20
Slide 20 text
A . ւ ֎ Ͱ ൺ ֱ త ༗ ໊
Slide 21
Slide 21 text
Q . ຊ Ͱ ͷ ໊ ʁ
Slide 22
Slide 22 text
A . 2 0 1 1 ຊ ֨ త ʹ ຊ ্
Slide 23
Slide 23 text
2 0 1 1 ʹ ຊ ʹ ্
Slide 24
Slide 24 text
ٕ ज़ ධ ࣾ Ͱ ి ࢠ ॻ ੶ Խ
Slide 25
Slide 25 text
Q . ϚΠφ ʔ ͳ ݴ ޠ ͳ ͷ ʹ Ͳ ͏ ͯ͠ …
Slide 26
Slide 26 text
No content
Slide 27
Slide 27 text
͋ͬɾɾɾ(͠)
Slide 28
Slide 28 text
͋ͬɾɾɾ(͠)
Slide 29
Slide 29 text
5 Ͱ ͔ Δ N I M
• खଓ͖ܕ੩తܕ͚
• ଟ༷ͳಛΛ࣋ͪ߹ΘͤΔ
• खଓ͖ܕ
• ΦϒδΣΫτࢦܕ
• ؔܕ
• δΣωϦοΫϓϩάϥϛϯά
Slide 30
Slide 30 text
5 Ͱ ͔ Δ N I M
• நߏจ͋Γ
• LISP ͔ΒӨڹ
• ڧྗͳϚΫϩ
• DSL Λ࡞͍͢͠
• ੩తܕ͚ͱಈతܕ͚ͷ͍͍ͱ͜औΓ
• ίϯύΠϧ࣮ͯ͠ߦՄೳܗࣜͷϑΝΠϧΛੜՄೳ
• ΨϕʔδίϨΫγϣϯΛࡌ
Slide 31
Slide 31 text
ଓ ͖
Slide 32
Slide 32 text
ง ғ ؾ
Slide 33
Slide 33 text
ؓ ٳ ɻ
Slide 34
Slide 34 text
S P RY ! ! !
Slide 35
Slide 35 text
S P RY ͷ ֓ ཁ
A B O U T S P RY
Slide 36
Slide 36 text
S P RY ͷ ֓ ཁ
• Nim Ͱॻ͔Εͨ VM
• C/C++ JavaScript ʹίϯύΠϧͰ͖Δ
• ͞·͟·ͳݴޠͷಛΛऔΓೖΕ͍ͯΔ
• Smalltalk, Rebol, Lisp, JavaScript, Forth, Nim
Slide 37
Slide 37 text
S P RY ͷ ಛ
F E A T U R E S O F S P RY
Slide 38
Slide 38 text
S P RY ͷ ಛ - ެ ࣜ αΠ τ ͔ Β ͷ Ҿ ༻
• ϛχϚϦζϜͰಈతܕ͚
• ਅʹϗϞΠίχοΫ
• ͕ͯ͢ AST ͱͯ͠දݱ͞Ε͍ͯΔ
• ΈࠐΈͷΩʔϫʔυͳ͍
• ͯ͢ͷॲཧؔʹׂΓͯͯߦ͏
Slide 39
Slide 39 text
S P RY ͷ ಛ ( C O N T. D )
• Smalltalk ͷΑ͏ͳΩʔϫʔυҾΛαϙʔτ
• ܰྔͳແ໊ؔΛΫϩʔδϟʹΑ࣮ͬͯݱ
• Smalltalk ͷΑ͏ʹ non local return ελΠϧ
• C/C++ Nim ͷࢿ࢈Λੜ͔ͤΔ
Slide 40
Slide 40 text
S P RY ͷ ಛ ( C O N T. D )
• Nim ͷ͍͍ͱ͜Ζ͕ͦͷ··
• εϨουωΠςΟϒ
• ΨϕʔδίϨΫγϣϯߴੑೳ
• ϑοτϓϦϯτ͕খ͍͞ΠϯλϓϦλ
• ελςΟοΫͳΠϯλϓϦλ͕ 100KB લޙͷαΠζ
• Nim Ͱ͓Αͦ 2300ߦ
Slide 41
Slide 41 text
N I M ͷ ಛ ( C O N T. D )
• ଟݴޠͱੑ͕Α͍
• C/C++ ʹมՄೳ
• JavaScript ʹมՄೳ
• REPL Λࡌ
• ispry ίϚϯυͰର
• ΣϒαΠτͰࢼͤΔ
• ## 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.
Slide 52
Slide 52 text
ͬͯ Έ ͨ
$ 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'
Slide 53
Slide 53 text
L Z 4 ͕ ݟ ͭ ͔ Β ͳ ͍
υ Ω ϡ ϝ ϯ τ ෆ උ Ͱ …
Slide 54
Slide 54 text
ਖ਼ ղ
• brew install lz4
• nimble install nimlz4
• nim c -d:release spry
• nim c -d:release ispry
Slide 55
Slide 55 text
ί ʔ υ ྫ
E X A M P L E O F S P RY C O D E
Slide 56
Slide 56 text
ఆ ٛ
'to:do: = method [:to :block
n = self
[n <= to] whileTrue: [
do block n
..n = (n + 1)]]
Slide 57
Slide 57 text
͍ ํ
1 to: 5 do: [echo :x]
1
2
3
4
5
Slide 58
Slide 58 text
ఆ ٛ
'select: = method [:pred
result = ([] clone)
self reset
[self end?] whileFalse: [
n = (self next)
do pred n then: [result add: n]]
^result]
Slide 59
Slide 59 text
͍ ํ
echo ([1 2 3 4] select: [:x > 2])
3 4
Slide 60
Slide 60 text
؆ ୯ ͳ ν ϡ ʔ τ Ϧ Ξϧ ͋ Γ · ͢
I S P RY + T U T O R I A L 1 . S Y
Slide 61
Slide 61 text
S P RY ͷ จ ๏
S Y N TA X O F S P RY
Slide 62
Slide 62 text
L A N G U A G E M A N U A L Α Γ ൈ ਮ
Slide 63
Slide 63 text
L A N G U A G E M A N U A L
• Comments
• Literals
• Words
• Precedence
• Booleans
• Nil and Undef
Slide 64
Slide 64 text
L A N G U A G E M A N U A L
• Composities
• Root
• Functions and Methods
• Scoping
• Standard Library
Slide 65
Slide 65 text
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”
Slide 66
Slide 66 text
W O R D S
• มͷΑ͏ͳͷ
• औಘʹ $ Λ͏
• ධՁʹԿ͚ͭͳ͍
• Ϧςϥϧͷ Word ͷهड़ʹ ‘
• ͍͍ͩͨγϯϘϧͩͱࢥ͓͚ͬͯΑ͍
Slide 67
Slide 67 text
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
Slide 68
Slide 68 text
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"]
Slide 69
Slide 69 text
N I L A N D U N D E F
• ະఆٛͷม undef
• nil Կͳ͍͜ͱΛද͢
• undef ͱ nil ͷҙຯ߹͍ҟͳΔ
• ྆ํͱ Word ͱͯ͠ଘࡏ͢Δͷಉ͡
Slide 70
Slide 70 text
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"
Slide 71
Slide 71 text
C O M P O S I T E S - B L O C K
• [ ͱ ] ͷΞϨ
• do ؔͰධՁͰ͖Δ
• ॻ͖͑Մೳ
• ͳΜͯڪΖ͍͜͠ͱΛ…
• Smalltalk ͷ OrderedCollection ʹ૬͢Δ
Slide 72
Slide 72 text
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
Slide 73
Slide 73 text
C O M P O S I T E S - PA R E N
• ( ͱ )
• ධՁͷ༏ઌॱҐΛ੍ޚ
• Block ͱಉ͡Α͏ʹධՁʹ͑Δ
• ݁Ռͷ࠷ޙͷࣜͱͳΔ
Slide 74
Slide 74 text
C O M P O S I T E S - C U R LY
• { ͱ }
• ࿈ྻʹ͏
map = {x = 50 y = 100}
map at: ‘y # => 100
Slide 75
Slide 75 text
C O M P O S I T E S - M A P
• { ͱ } Λͬͯ࡞ͬͨϠπ
• Ωʔʹ 11छྨͷ Word ͕͑Δ
• $foo, foo, :foo ۠ผ͞ΕΔ
• ‘$foo ͱ ‘foo ҟͳΔ
Slide 76
Slide 76 text
R O O T
• Smalltalk Ͱ͍͏ͱ͜Ζͷ Smalltalk Dictionary
• Spry Ͱ root ͱݺΜͰ͍Δ
• ϞδϡʔϧͳͲ root Ͱͳ໊͍લۭؒʹஔ
Slide 77
Slide 77 text
F U N C T I O N S A N D M E T H O D S
• Func
• func ؔͰ Block ͔Β࡞ͬͨϠπ
• Func ϒϩοΫ͕ධՁ͞ΕΔͱ͖ʹධՁ͞ΕΔ
• ॻ͍ͯΔ͜ͱΑ͔͘Μͳ͍͚Ͳߴ֊͕ؔ࡞ΕΔͬΆ͍
• Methods
• ϓϩτλΠϓͷΦϒδΣΫτࢦͬΆ͍͜ͱ͕Ͱ͖Δ
• ϞδϡʔϧͷΠϯΫϧʔυʹࣅ͍ͯΔࣈ໘
Slide 78
Slide 78 text
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
Slide 79
Slide 79 text
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)"
Slide 80
Slide 80 text
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"
Slide 81
Slide 81 text
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"
Slide 82
Slide 82 text
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
Slide 83
Slide 83 text
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
Slide 84
Slide 84 text
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
Slide 85
Slide 85 text
S TA N D A R D L I B R A RY
• ଟ࠼ͳϥΠϒϥϦ
• σβΠϯύλʔϯ
• ϦϑϨΫγϣϯ
• ࢛ଇԋࢉɾൺֱ
• ͳͲͳͲ
Slide 86
Slide 86 text
S TA N D A R D L I B R A RY
• ΈࠐΈͷϫʔυʹ͍ͭͯղઆ͞Ε͍ͯΔ
• ͍͜ͳ͢ʹҰ௨Γ͜ΕΛಡΉ͠
• ͪΐͬͱΫη͕͋Δ
• ifTrue: ΑΓ͍ then: Ͱॻ͚ΔͥʢυϠΝ