Sasada Yusuke Endoh Dmitry Petrashko and Sorbet team (Sorbet) Jeff Foster (RDL) Yusuke Endoh (type-profiler) Soutaro Matsumoto (Steep) Have meetings to share the progress and develop the foundation of type checking for Ruby
• To help development of Ruby programs • Finding bugs (NoMethodErrors) • Reading code: jump to definition • Refactoring: renaming constants, methods, ... • Performance is not our goal (it needs much more precise analysis)
Library code type signature Type error warnings Application code type signature type signature Type Profiler Type error warnings 3. Type signature profiling 2. Level-1 checking 4. Level-2 checking 1. Type signature format
you need the signatures of libraries • Standard library and gems • You don't want to write yourself • Ruby3 will ship with standard library signatures • Ruby3 will define the standard protocol to share signature of gems
(A, X) -> A } -> A ... end New type annotation syntax (rejected in Ruby3) # @type method inject: [A] (A) { (A, Elm) -> A } -> A def inject(start) end Type annotation using comment (Steep)
(A, X) -> A } -> A ... end New type annotation syntax (rejected in Ruby3) # @type method inject: [A] (A) { (A, Elm) -> A } -> A def inject(start) end Type annotation using comment (Steep) sig { type_parameters(:U). .params(start: T.type_parameter(:U), blk: T.proc.params(arg0: Elem, T.type_parameter(:A)).returns(T.type_parameter(:U))) .returns(T.type_parameter(:A)) } def inject(start, &blk) end Type annotation using embedded DSL (Sorbet)
tools are not a part of Ruby3 • No tool works as Matz expected... • Steep requires too much annotations • Sorbet's modeling of duck typing requires extra code • type-profiler is still too experimental
to define signatures of Ruby programs • Signature of standard library • A protocol to share the signatures of gems • Ruby3 won't provide: • New syntax to annotate Ruby code • The standard type checker
your project • My recommendation is level 2 Library Application Type checking Tools Level 0 No No No --- Level 1 Use library signatures No signature Weaker type-profiler Level 2 Use library signatures You write signature Stronger Sorbet, Steep
(name: String) -> void def speakers: -> Array<Speaker> end class Talk ... end class Speaker ... end class Conference attr_reader :name attr_reader :talks def initialize(name:) @name = name @talks = [] end def speakers talks.each(&:speaker) end end conference = Conference.new("BalkanRuby 2019") conference.talks << Talk.new(...)
name @talks = [] end def speakers talks.each(&:speaker) end end conference = Conference.new("Balkan Ruby 2019") conference.talks << Talk.new(...) class Conference attr_reader name: String attr_reader talks: Array<Talk> def initialize: (name: String) -> void def speakers: -> Array<Speaker> end class Talk ... end class Speaker ... end MethodBodyTypeMismatch: method=speakers, expected=::Array<::Speaker>, actual=::Array<::Talk>
detects type errors on metaprogramming method calls • It doesn't know the result of metaprogramming • You can use any metaprogramming as you like class Person # Error: attr_reader doesn't accept class attr_reader Name end class Class def attr_reader: (*Symbol|String) -> ... end class Person @name: Name def name: -> Name end
comments • Embedded DSL requires extra runtime dependency • Better for libraries: • Keep # of runtime dependencies as small as possible • Your library users would not want to install Steep spec.add_development_dependency "steep"
Type definition language • Develop a ruby library to process type definitions • https://github.com/ruby/ruby-signature • Library types • Writing signature of standard libraries • Starting a discussion for gem types
with signature files • Include signature files in the .gem • Declare in metadata that the gem has signatures Gem::Specification.new do |spec| spec.name = "rakia" spec.files = ["lib/rakia.rb", "sig/rakia.rbi"] spec.metadata = { "signature_dir" => "sig" } end
gem signatures for the case the authors don't provide signatures (DefinitelyTyped in TypeScript) source "https://rubygems.org" gem "rails", version: "~> 6.0.0" gem "type--rails"
type checkers with your programs • $ gem install steep • Sign up Sorbet beta program • Try writing types for your gems/apps • Send a patch to add standard library signatures • https://github.com/ruby/ruby-signature