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

Intro to Crystal Language

Intro to Crystal Language

What is Crystal Language?

Talk presented online at RubyConfOnline December 2015.

Luis Lavena

December 02, 2015
Tweet

More Decks by Luis Lavena

Other Decks in Programming

Transcript

  1. Crystal Language https://crystal-lang.org

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

  3. What if Ruby was created today?

  4. Overview of features • LLVM-backend • Ruby-like syntax • Compiles

    to native code • Global type inference • Compile time error checking • Go-inspired concurrency design*
  5. 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
  6. 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)
  7. Ruby-like syntax, on steroids • Initializer shortcuts • Method overloading

    • Macros • Generics • 21st century Standard Library
  8. Initializer shortcuts # Ruby class Greeter def initialize(entity) @entity =

    entity end end # Crystal class Greeter def initialize(@entity) end end
  9. 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!"
  10. 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!"
  11. 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?
  12. Macros (expanded) class Person getter name end class Person def

    name @name end end
  13. Type inference • Always know what is being used and

    where • Compile time checks beats runtime errors ;-)
  14. Types • String is not the same as Char ◦

    “a” vs ‘a’ • Int32 and Int64 • Float32 and Float64 • Nil • Boolean • Array of types (Array(T))
  15. 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)
  16. Modern Standard Library • No legacy libraries ;-) • HTTP

    Client and Servers built-in • OAuth2 and Websockets • YAML, JSON, XML, Markdown parsers • Growing ecosystem (shards)
  17. 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
  18. HTTP Server $ crystal build --release http_server.cr $ ./http_server Listening

    on http://0.0.0.0:9292
  19. 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
  20. 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)
  21. 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
  22. 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
  23. HTTP Client require "http/client" response = HTTP::Client.get "http://www.example.com" response.status_code #

    => 200 response.body.lines.first # => "<!doctype html>"
  24. JSON Parsing (schema) require "json" class Person JSON.mapping({ name: String,

    age: Int32, }) end
  25. 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
  26. JSON Parsing class Person # … mapping … def initialize(@name,

    @age) end end user = Person.new("Aaron", 34) user.to_json # => {"name":"Aaron","age":34}
  27. https://github.com/kostya/benchmarks#json

  28. Ecosystem (shards) • Bundler-like • Decentralized • Git-based • shard.yml

    & shard.lock
  29. Awesome, does it run Rails?

  30. No

  31. No

  32. Web frameworks • Amethyst • Kemal • Moonshine • Carbon

    • Chocolate • Beryl* https://github.com/veelenga/awesome-crystal
  33. Simplified deployment • Single executable • Small footprint and size

    • Fast compile times • Easy Heroku deploy* https://github.com/scaint/heroku-buildpack-crystal
  34. Community • Small, friendly • Code of Conduct • New

    language, fewer libraries • 3rd party libraries starting to show • Less drama ;-) https://github.com/veelenga/awesome-crystal
  35. 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
  36. Thanks! github.com/luislavena