Date post: | 07-Jan-2017 |
Category: |
Technology |
Upload: | ruby-meditation |
View: | 45 times |
Download: | 1 times |
ABOUT ME
• Mikhail Bortnyk
• Too old for this shit
• Work for Amoniac OÜ
• Ruby developer
• Language researcher
ABOUT ME
• Mikhail Bortnyk
• Too old for this shit
• Work for Amoniac OÜ
• Ruby developer
• Language researcher
• kottans.org co-founder
ABOUT ME
• Mikhail Bortnyk
• Too old for this shit
• Work for Amoniac OÜ
• Ruby developer
• Language researcher
• kottans.org co-founder
• twitter @mikhailbortnyk
SIDE EFFECTS
PROBLEM 1.1
• your objects store state
• your code modifies state
• your other code modifies state too
SIDE EFFECTS
PROBLEM 1.1
• your objects store state
• your code modifies state
• your other code modifies state too
• summary: mess
SIDE EFFECTS
PROBLEM 1.1
• your objects store state
• your code modifies state
• your other code modifies state too
• summary: mess
LIMITS ARE FREEING
CLEAN YOUR RUBY
• David Copeland article “Adventures in functional programming with Ruby”
LIMITS ARE FREEING
CLEAN YOUR RUBY
• David Copeland article “Adventures in functional programming with Ruby”
• Loops are just functions
LIMITS ARE FREEING
CLEAN YOUR RUBY
• David Copeland article “Adventures in functional programming with Ruby”
• Loops are just functions
• Data structures are just functions
LIMITS ARE FREEING
CLEAN YOUR RUBY
• David Copeland article “Adventures in functional programming with Ruby”
• Loops are just functions
• Data structures are just functions
• Objects are just functions
LIMITS ARE FREEING
CLEAN YOUR RUBY
• David Copeland article “Adventures in functional programming with Ruby”
• Loops are just functions
• Data structures are just functions
• Objects are just functions
• Namespaces are just functions
LIMITS ARE FREEING
CLEAN YOUR RUBY
• David Copeland article “Adventures in functional programming with Ruby”
• Loops are just functions
• Data structures are just functions
• Objects are just functions
• Namespaces are just functions
• P.S. Ruby HAS Tail Call Optimization
ROUGH HACK
TAIL-CALL OPTIMIZATION
def fact(n, acc=1) return acc if n <= 1 fact(n-1, n*acc) end
RubyVM::InstructionSequence.compile_option = { tailcall_optimization: true, trace_instruction: false }
fact(1000)
FUNCTIONAL VS OBJECT-ORIENTED
SIDE TO SIDE COMPARISON
new_person = ->(name, birthdate, gender, title, id=nil) { return ->(attribute) { return id if attribute == :id return name if attribute == :name return birthdate if attribute == :birthdate return gender if attribute == :gender return title if attribute == :title nil } }
class Person attr_reader :id, :name, :birthdate, :gender, :title def initialize(name, birthdate, gender, title, id=nil) @id = id @name = name @birthdate = birthdate @gender = gender @title = title end end
SPECIAL KNOWLEDGE
WHAT’S WRONG WITH OO-CODE?
• WTF is “class”
• WTF are .new and initialize
• API of class
SPECIAL KNOWLEDGE
WHAT’S WRONG WITH OO-CODE?
• WTF is “class”
• WTF are .new and initialize
• API of class
• WTF are @-variables
SPECIAL KNOWLEDGE
WHAT’S WRONG WITH OO-CODE?
• WTF is “class”
• WTF are .new and initialize
• API of class
• WTF are @-variables
• difference between class and instance
SPECIAL KNOWLEDGE
WHAT’S WRONG WITH OO-CODE?
• WTF is “class”
• WTF are .new and initialize
• API of class
• WTF are @-variables
• difference between class and instance
• WTF is “attr_reader”
TO DON’T SHOOT YOUR LEG
SAFETY RULES
• do not modify, create new
• BUY MORE RAM
• functions should not depend on environment
TO DON’T SHOOT YOUR LEG
SAFETY RULES
• do not modify, create new
• BUY MORE RAM
• functions should not depend on environment
• BUY EVEN MORE RAM
TO DON’T SHOOT YOUR LEG
SAFETY RULES
• do not modify, create new
• BUY MORE RAM
• functions should not depend on environment
• BUY EVEN MORE RAM
• avoid returns
TO DON’T SHOOT YOUR LEG
SAFETY RULES
• do not modify, create new
• BUY MORE RAM
• functions should not depend on environment
• BUY EVEN MORE RAM
• avoid returns
• use lambdas
TO DON’T SHOOT YOUR LEG
SAFETY RULES
• do not modify, create new
• BUY MORE RAM
• functions should not depend on environment
• BUY EVEN MORE RAM
• avoid returns
• use lambdas
• DO NOT FORGET TO ORDER RAM RIGHT NOW
SIDE TO SIDE RULES COMPARISON
FUNCTIONAL VS OBJECT-ORIENTED
• how to perform tasks and how to track changes
• state changes are important
• order of execution is important
• flow controlled by loops, conditionals, function calls
• instances of structures and classes
• focus on what information is needed and what transformations required
• state changes are non-existent
• order of execution is low-important
• flow controlled by function calls including recursion
• functions are first class objects, data collections
— Greenspun’s tenth rule of programming
ANY SUFFICIENTLY COMPLICATED C OR FORTRAN PROGRAM CONTAINS AN AD-HOC, INFORMALLY-SPECIFIED, BUG-RIDDEN, SLOW
IMPLEMENTATION OF HALF OF COMMON LISP.
”
“
STILL EVOLVING!
FUNCTIONAL-RUBY GEM
• created by Jerry D’Antonio
• inspired by Erlang, Clojure, Haskell and Functional Java
STILL EVOLVING!
FUNCTIONAL-RUBY GEM
• created by Jerry D’Antonio
• inspired by Erlang, Clojure, Haskell and Functional Java
• has records, unions and tuples
STILL EVOLVING!
FUNCTIONAL-RUBY GEM
• created by Jerry D’Antonio
• inspired by Erlang, Clojure, Haskell and Functional Java
• has records, unions and tuples
• has protocols
STILL EVOLVING!
FUNCTIONAL-RUBY GEM
• created by Jerry D’Antonio
• inspired by Erlang, Clojure, Haskell and Functional Java
• has records, unions and tuples
• has protocols
• has Erlang-style pattern matching
STILL EVOLVING!
FUNCTIONAL-RUBY GEM
• created by Jerry D’Antonio
• inspired by Erlang, Clojure, Haskell and Functional Java
• has records, unions and tuples
• has protocols
• has Erlang-style pattern matching
• has function memoization
STILL EVOLVING!
FUNCTIONAL-RUBY GEM
• created by Jerry D’Antonio
• inspired by Erlang, Clojure, Haskell and Functional Java
• has records, unions and tuples
• has protocols
• has Erlang-style pattern matching
• has function memoization
• supports MRI, JRuby and Rubinius
PATTERN MATCHING AND TYPE CHECKING
FUNCTIONAL-RUBY GEM
class Yoga include Functional::PatternMatching include Functional::TypeCheck
defn(:where_is_sun) do puts "\\o" end
defn(:where_is_sun, 14) do puts "88!" end
defn(:where_is_sun, _) do |name| puts "\\o, #{name}!" end
defn(:where_is_sun, _) do |name| puts "Are you in wrong district, #{name.rude_name}?" end.when { |name| Type?(name, Moskal) }
defn(:where_is_sun, _, _) do |name, surname| "\\o, #{name} #{surname}!" end end
MEMOIZATION
FUNCTIONAL-RUBY GEM
class Factors include Functional::Memo
def self.sum_of(number) of(number).reduce(:+) end
def self.of(number) (1..number).select {|i| factor?(number, i)} end
def self.factor?(number, potential) number % potential == 0 end
memoize(:sum_of) memoize(:of) end
RECORDS
FUNCTIONAL-RUBY GEM
Name = Functional::Record.new(:first, :middle, :last, :suffix) do mandatory :first, :last default :first, 'J.' default :last, 'Doe' end