Slide 1

Slide 1 text

Ruby Programming with Static Type Checking Soutaro Matsumoto
 @soutaro

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

@soutaro on GitHub/Twitter

Slide 4

Slide 4 text

from Tokyo, Japan

Slide 5

Slide 5 text

CTO at Sider,
 an automated code review service

Slide 6

Slide 6 text

Steep, Gradual Typing for Ruby

Slide 7

Slide 7 text

–Matz (RubyKaigi 2016) “We need something similar to static type checks.”

Slide 8

Slide 8 text

Type Checkers for Ruby • Steep: https://github.com/soutaro/steep • Sorbet: https://sorbet.run • RDL: https://github.com/plum-umd/rdl • mruby-meta-circular: https://github.com/miura1729/ mruby-meta-circular

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

What is Type Checking • A program verification based on type system (without executing the program) • Detect some kind of errors: NoMethodError, ArgumentError, null dereferencing, ... • You can do that with tests (but they depend on execution paths)

Slide 11

Slide 11 text

Type Checking for Ruby • Pros • Confidence that your program won't raise the errors (correctness) • Cons • Sacrifice some flexibilities of Ruby programming • Extra declaration or annotation of types

Slide 12

Slide 12 text

Type Checking Properties • Correctness: If type checking says your program is ok, no runtime error will be raised during execution • Flexibility: Type checker can accept more Ruby programs • Number of annotations: Ruby programmers don't want to write type annotations

Slide 13

Slide 13 text

Designing Type Checker • Keep it as correct as possible • More flexibility with annotations • Declare type of classes/modules/methods explicitly • Write type annotations in Ruby code if necessary (local type inference to minimize # of annotations) • Steep follows this strategy

Slide 14

Slide 14 text

Steep Quick Tour 1. Write type definitions 2. Write Ruby code 3. Write type annotations if necessary 4. Run type checker $ gem install steep https://github.com/soutaro/steep

Slide 15

Slide 15 text

Write Type Definitions class Meetup attr_reader talks: Array attr_reader capacity: Integer @all_attendees: Array def initialize: (capacity: Integer, talks: Array) -> any def each_attendee: { (Attendee) -> void } -> void | -> Enumerable def <<: (Attendee) -> self def attending?: (Attendee) -> bool def spots_left?: () -> bool end

Slide 16

Slide 16 text

Write Ruby Program class Meetup def spots_left? @attendees.size < capacity end def <<(attendee) raise "Meetup is full!" unless spots_left? raise "Already registered!" if attending?(attendee) @attendees << attendee self end def attending?(attendee) each_attendee.include?(attendee) end ... end

Slide 17

Slide 17 text

Write Ruby Program def spots_left? @attendees < capacity end meetup.rb:3:4: NoMethodError: type=::Array<::Attendee>, method=< (@attendees < capacity)

Slide 18

Slide 18 text

Write Type Annotations • Some Ruby code requires type annotations (or casts) # @type var attendees: Array attendees = [] attendees.push Attendee.new(...) # @type var number: Integer number = object.__send__(:to_i) # @type var number: Integer number = _ = "string"

Slide 19

Slide 19 text

Ruby Programming with Steep • Does it support duck typing? • Types of gems? • Linters and editors? • Is type checking required?

Slide 20

Slide 20 text

Duck Typing? • Object types are type checked with the methods and their types class Attendee def join(collection) collection << self end ... end attendee.join(Meetup.new) # OK attendee.join([]) # OK attendee.join("") # Error Any object is ok if it has << operator which accepts Attendee

Slide 21

Slide 21 text

Duck Typing? • Meetup#<<: (Attendee) -> Meetup • Array#<<: (Attendee) -> Array • String#<<: (String) -> String interface _Attendable def <<: (Attendee) -> self end class Attendee def join: (_Attendable) -> void ... end

Slide 22

Slide 22 text

Types of Gems? • Some gems will ship with their type definitions • I'm planning to have community managed type definition repository: major gems will have type definitions • We will have to write type definitions by ourselves for minor gems

Slide 23

Slide 23 text

Linters and Editors • They will be smarter if integrated with Steep • They will know types of variables and expressions • Smarter auto-completion • Better refactoring support • More suggestions for improvements

Slide 24

Slide 24 text

Is Type Checking Required? • No, it's optional for Ruby • There are several levels how you adapt to type checking: • Type check all of your code • Type check part of your code (some .rb files) • Declare types but skip checking implementation • No type declaration but checks your code against gem types • No type checking at all

Slide 25

Slide 25 text

Conclusion • We are working for type checking for Ruby • There are some projects related to types for Ruby • Looking forward to hearing feedbacks from you