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

Typed Ruby

Typed Ruby

Ruby has is a dynamic language, it has no types, why would we care?

Nikita Shilnikov

October 21, 2017
Tweet

More Decks by Nikita Shilnikov

Other Decks in Programming

Transcript

  1. => [:%, :&, :*, :+, :-, :/, :<, :>, :^,

    :|, :~, :-@, :**, :<=>, :<<, :>>, :<=, :>=, :==, :===, :[], :inspect, :size, :succ, :to_int, :to_s, :to_i, :to_f, :next, :div, :upto, :chr, :ord, :coerce, :divmod, :fdiv, :modulo, :remainder, :abs, :magnitude, :integer?, :floor, :ceil, :round, :truncate, :odd?, :even?, :downto, :times, :pred, :bit_length, :digits, :to_r, :numerator, :denominator, :rationalize, :gcd, :lcm, :gcdlcm, :+@, :eql?, :singleton_method_added, :i, :real?, :zero?, :nonzero?, :finite?, :infinite?, :step, :positive?, :negative?, :quo, :arg, :rectangular, :rect, :polar, :real, :imaginary, :imag, :abs2, :angle, :phase, :conjugate, :conj, :to_c, :between?, :clamp, :instance_of?, :kind_of?, :is_a?, :tap, :public_send, :remove_instance_variable, :public_method, :singleton_method, :instance_variable_set, :define_singleton_method, :method, :extend, :to_enum, :enum_for, :=~, :!~, :respond_to?, :freeze, :object_id, :send, :display, :nil?, :hash, :class, :singleton_class, :clone, :dup, :itself, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variable_get, :instance_variables, :instance_variable_defined?, :!, :!=, :__send__, :equal?, :instance_eval, :instance_exec, :__id__]
  2. => [:%, :&, :*, :+, :-, :/, :<, :>, :^,

    :|, :~, :-@, :**, :<=>, :<<, :>>, :<=, :>=, :==, :===, :[], :inspect, :size, :succ, :to_int, :to_s, :to_i, :to_f, :next, :div, :upto, :chr, :ord, :coerce, :divmod, :fdiv, :modulo, :remainder, :abs, :magnitude, :integer?, :floor, :ceil, :round, :truncate, :odd?, :even?, :downto, :times, :pred, :bit_length, :digits, :to_r, :numerator, :denominator, :rationalize, :gcd, :lcm, :gcdlcm, :+@, :eql?, :singleton_method_added, :i, :real?, :zero?, :nonzero?, :finite?, :infinite?, :step, :positive?, :negative?, :quo, :arg, :rectangular, :rect, :polar, :real, :imaginary, :imag, :abs2, :angle, :phase, :conjugate, :conj, :to_c, :between?, :clamp, :instance_of?, :kind_of?, :is_a?, :tap, :public_send, :remove_instance_variable, :public_method, :singleton_method, :instance_variable_set, :define_singleton_method, :method, :extend, :to_enum, :enum_for, :=~, :!~, :respond_to?, :freeze, :object_id, :send, :display, :nil?, :hash, :class, :singleton_class, :clone, :dup, :itself, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variable_get, :instance_variables, :instance_variable_defined?, :!, :!=, :__send__, :equal?, :instance_eval, :instance_exec, :__id__]
  3. "t"

  4. Problems 1. Using models for coercion is questionable. 2. Coercion

    logic is opaque. 3. Types are defined by database columns. 4. Unhappy paths end with an error (better) or a data corruption (worse).
  5. What is a type? 1. A category of people or

    things having common characteristics. 2. A person or thing exemplifying the ideal or defining characteristics of something (prototype). 3. Characters or letters that are printed or shown on a screen.
  6. What is a type? 1. A category of people or

    things having common characteristics. 2. A person or thing exemplifying the ideal or defining characteristics of something (prototype). 3. Characters or letters that are printed or shown on a screen.
  7. A category of people or things having common characteristics 1.

    Natural numbers (1, 2, 3, 4, ...). 2. Emojis ( ...). 3. Vertebrates (dog, cat, horse, ...).
  8. Types in programming Also called data types. Play a major

    role in statically typed languages.
  9. 1. Early sanity-check, the compiler will check your code for

    consistency. 2. Advanced compilers can check a program for correctness. 3. Better semantics and docs. 4. Better introspection/IDE integration. 5. A lot of performance optimizations can be done during the compile phase. Pros:
  10. 1. Compilation takes time. 2. Types require more typing making

    code more verbose and less flexible. Cons:
  11. —a type system built for coercion and data validation; —formerly

    known as dry-data; —initially was created as a replacement for virtus; —is a direct dependency of dry-validation, ROM, and hanami-model. dry-types
  12. int = Types::Strict::Int int[3] # => 3 int['3'] # =>

    '3' violates constraints # (type?(Integer, '3') failed)
  13. module ProfileEvents class PasswordChanged < Dry::Struct attribute :user_id, Types::UUID attribute

    :password, Types::Password end class EmailChanged < Dry::Struct attribute :user_id, Types::UUID attribute :email, Types::Email end Updated = PasswordChanged | EmailChanged end
  14. module ProfileEvents class PasswordChanged < Dry::Struct attribute :user_id, Types::UUID attribute

    :password, Types::Password end class EmailChanged < Dry::Struct attribute :user_id, Types::UUID attribute :email, Types::Email end Updated = PasswordChanged | EmailChanged end
  15. module ProfileEvents class PasswordChanged < Dry::Struct attribute :user_id, Types::UUID attribute

    :password, Types::Password end class EmailChanged < Dry::Struct attribute :user_id, Types::UUID attribute :email, Types::Email end Updated = PasswordChanged | EmailChanged end
  16. age = Types::Strict::Int.constrained(gteq: 18) types = { age => :age

    } types[Types::Strict::Int.constrained(gteq: 18)] # => :age
  17. Types::Strict::String.constrained(min_size: 3) # => #<Dry::Types::Constrained type=#<Dry::Types::Definition primitive=String options={} meta={}> options={:rule=>#<Dry::Logic::Operations::And

    rules=[#<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#type?> options={:args=>[String]}>, #<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#min_size?> options={:args=>[3]}>] options={}>} rule=#<Dry::Logic::Operations::And rules=[#<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#type?> options={:args=>[String]}>, #<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#min_size?> options={:args=>[3]}>] options={}> meta={}>
  18. Recap — Duck typing is neither about ducks nor typing.

    — Types are sets of possible values that shape the data. — In dry-types types are ordinary objects that can be build and composed. — Types can even be decomposed allowing you to build new abstractions on top of them.