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?

Avatar for Nikita Shilnikov

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.