Slide 1

Slide 1 text

Crystal Language https://crystal-lang.org

Slide 2

Slide 2 text

Luis Lavena Work: area17.com Twitter: @luislavena GitHub: luislavena

Slide 3

Slide 3 text

What if Ruby was created today?

Slide 4

Slide 4 text

Overview of features ● LLVM-backend ● Ruby-like syntax ● Compiles to native code ● Global type inference ● Compile time error checking ● Go-inspired concurrency design*

Slide 5

Slide 5 text

LLVM-backend ● Used by many new languages (ie. Rust, Swift) ● Simplifies architecture porting and cross compilation ● Advanced branching and native code optimizations ● Stands on the shoulders of giants

Slide 6

Slide 6 text

Ruby-like syntax ● Reduces learning curve ● Inspired but not directly copied ● many ways to do things vs one way (no aliases) ● Compiled, no VM or bytecode to interpret ● No eval or crazy meta-programming ● Self-hosted (Crystal is written in Crystal)

Slide 7

Slide 7 text

Ruby-like syntax, on steroids ● Initializer shortcuts ● Method overloading ● Macros ● Generics ● 21st century Standard Library

Slide 8

Slide 8 text

Initializer shortcuts # Ruby class Greeter def initialize(entity) @entity = entity end end # Crystal class Greeter def initialize(@entity) end end

Slide 9

Slide 9 text

Method overload # Ruby def guess(value) case value when Integer puts "Integer!" when String puts "String!" else puts "No idea!" end end # Ruby guess 10 # => "Integer!" guess "hello!" # => "String!" guess true # => "No idea!"

Slide 10

Slide 10 text

Method overload # Crystal def guess(value : Int32) puts "Integer!" end def guess(value : String) puts "String!" end def guess(value) puts "No idea!" end # Crystal guess 10 # => "Integer!" guess "hello!" # => "String!" guess true # => "No idea!"

Slide 11

Slide 11 text

Macros ● Executed before type inference ● Transform AST at compilation time ● Used for minimal meta-programming and callbacks ○ inherited (Class) ○ included (Module) ○ method_missing ○ delegate ○ setter/getter/property ○ respond_to?

Slide 12

Slide 12 text

Macros (expanded) class Person getter name end class Person def name @name end end

Slide 13

Slide 13 text

Type inference ● Always know what is being used and where ● Compile time checks beats runtime errors ;-)

Slide 14

Slide 14 text

Types ● String is not the same as Char ○ “a” vs ‘a’ ● Int32 and Int64 ● Float32 and Float64 ● Nil ● Boolean ● Array of types (Array(T))

Slide 15

Slide 15 text

Types a = [1, 2, 3].map { |x| x + 3 } pp a # => a = [4, 5, 6] pp typeof(a) # => Array(Int32) b = [1, "a", 'b'] pp typeof(b) # => Array(String | Int32 | Char) # b << 12.5 # => Compile error (Float32)

Slide 16

Slide 16 text

Modern Standard Library ● No legacy libraries ;-) ● HTTP Client and Servers built-in ● OAuth2 and Websockets ● YAML, JSON, XML, Markdown parsers ● Growing ecosystem (shards)

Slide 17

Slide 17 text

HTTP Server require "http/server" server = HTTP::Server.new(9292) do |request| HTTP::Response.ok "text/plain", "Hello world!" end puts "Listening on http://0.0.0.0:9292" server.listen

Slide 18

Slide 18 text

HTTP Server $ crystal build --release http_server.cr $ ./http_server Listening on http://0.0.0.0:9292

Slide 19

Slide 19 text

HTTP Server (benchmark: wrk) $ ./wrk -c 10 -t 2 http://localhost:9292/ Running 10s test @ http://localhost:9292/ 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 97.90us 212.99us 13.47ms 99.67% Req/Sec 55.93k 4.88k 112.00k 90.55% 1118367 requests in 10.10s, 107.72MB read Requests/sec: 110733.34 Transfer/sec: 10.67MB

Slide 20

Slide 20 text

HTTP Server (prefork) require "http/server" server = HTTP::Server.new(9292) do |request| HTTP::Response.ok "text/plain", "Hello world!" end puts "Listening on http://0.0.0.0:9292" server.listen_fork(3)

Slide 21

Slide 21 text

HTTP Server (benchmark: wrk) $ ./wrk -c 10 -t 2 http://localhost:9292/ Running 10s test @ http://localhost:9292/ 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 128.90us 525.80us 12.09ms 97.18% Req/Sec 87.02k 17.70k 117.77k 63.50% 1731802 requests in 10.01s, 166.81MB read Requests/sec: 173042.01 Transfer/sec: 16.67MB

Slide 22

Slide 22 text

HTTP Server (memory) # fresh $ pmap -x $(http_server PID) Address Kbytes RSS Dirty total kB 69772 4408 776 total kB 111224 5116 1316 total kB 70264 4956 1156 Start wrk GC

Slide 23

Slide 23 text

HTTP Client require "http/client" response = HTTP::Client.get "http://www.example.com" response.status_code # => 200 response.body.lines.first # => ""

Slide 24

Slide 24 text

JSON Parsing (schema) require "json" class Person JSON.mapping({ name: String, age: Int32, }) end

Slide 25

Slide 25 text

JSON Parsing data = %([{"name":"Luis","age":36},{"name":"Ana","age":21}]) Array(Person).from_json(data).each do |person| if person.age > 30 puts "Getting old, #{person.name}?" end end

Slide 26

Slide 26 text

JSON Parsing class Person # … mapping … def initialize(@name, @age) end end user = Person.new("Aaron", 34) user.to_json # => {"name":"Aaron","age":34}

Slide 27

Slide 27 text

https://github.com/kostya/benchmarks#json

Slide 28

Slide 28 text

Ecosystem (shards) ● Bundler-like ● Decentralized ● Git-based ● shard.yml & shard.lock

Slide 29

Slide 29 text

Awesome, does it run Rails?

Slide 30

Slide 30 text

No

Slide 31

Slide 31 text

No

Slide 32

Slide 32 text

Web frameworks ● Amethyst ● Kemal ● Moonshine ● Carbon ● Chocolate ● Beryl* https://github.com/veelenga/awesome-crystal

Slide 33

Slide 33 text

Simplified deployment ● Single executable ● Small footprint and size ● Fast compile times ● Easy Heroku deploy* https://github.com/scaint/heroku-buildpack-crystal

Slide 34

Slide 34 text

Community ● Small, friendly ● Code of Conduct ● New language, fewer libraries ● 3rd party libraries starting to show ● Less drama ;-) https://github.com/veelenga/awesome-crystal

Slide 35

Slide 35 text

Useful resources ● Docs: http://crystal-lang.org/docs/ ● API: http://crystal-lang.org/api/ ● Group: https://groups.google.com/group/crystal-lang ● Twitter: https://twitter.com/CrystalLanguage ● Awesome: https://github.com/veelenga/awesome-crystal

Slide 36

Slide 36 text

Thanks! github.com/luislavena