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)
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
• 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
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
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
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
with Steep • They will know types of variables and expressions • Smarter auto-completion • Better refactoring support • More suggestions for improvements
• 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