SlideShare a Scribd company logo
1 of 54
Download to read offline
Friday, April 5, 13
Feel Objects
                      Pattern Matching in Ruby




Friday, April 5, 13
Name: Ryan Levick



Friday, April 5, 13
Work: 6Wunderkinder



Friday, April 5, 13
Twitter: @itchyankles



Friday, April 5, 13
Friday, April 5, 13
What the hell is pattern
                      matching and why should I
                                care?



Friday, April 5, 13
Wikipedia Definition


                      “...the act of checking a perceived
                      sequence of tokens for the presence of
                      the constituents of some pattern.”




Friday, April 5, 13
Wat?



Friday, April 5, 13
My Best Try

                      Checking a data type against some
                      predefined patterns, and when that data
                      type matches one of the predefined
                      patterns, do something.



Friday, April 5, 13
In Short...


                      Pattern matching is another way
                      to do control flow.




Friday, April 5, 13
Death to “if-then-else”!



Friday, April 5, 13
Friday, April 5, 13
ein Beispiel



Friday, April 5, 13
fun sum(numbers) =
                        case numbers of
                         []    => 0
                         x::xs => x + sum(xs)




Friday, April 5, 13
I don’t know SML. What the hell is this?




Friday, April 5, 13
Function declaration
                      fun sum(numbers) =
                        case numbers of
                             []       => 0
                             x::xs => x + sum(xs)




Friday, April 5, 13
Case statement matching against the list “numbers”.
                      fun sum(numbers) =
                          case numbers of
                            []       => 0
                            x::xs => x + sum(xs)




Friday, April 5, 13
First pattern
                      fun sum(numbers) =
                          case numbers of
                            []        => 0
                            x::xs => x + sum(xs)




Friday, April 5, 13
Second pattern
                      fun sum(numbers) =
                          case numbers of
                           []          => 0
                           x::xs => x + sum(xs)




Friday, April 5, 13
So let’s call it!



Friday, April 5, 13
val numbers = [1, 6, 8]
                      sum(numbers)




Friday, April 5, 13
sum([1, 6, 8]) =
                        case numbers of
                         []    => 0
                         x::xs => x + sum(xs)




Friday, April 5, 13
What pattern does
                       numbers match?


Friday, April 5, 13
x::xs => x + sum(xs)


                      1::[6, 8] => 1 + sum([6, 8])




Friday, April 5, 13
x::xs => x + sum(xs)


                      6::[8] => 1 + 6 + sum([8])




Friday, April 5, 13
x::xs => x + sum(xs)


                      8::[] => 1 + 6 + 8 + sum([])




Friday, April 5, 13
sum([]) =
                        case numbers of
                         []       => 0
                         x::xs => x + sum(xs)



Friday, April 5, 13
What pattern does
                       numbers match?


Friday, April 5, 13
[] => 1 + 6 + 8 + 0


                      15




Friday, April 5, 13
Pretty easy, and could be implemented in
                      roughly the same amount of characters with
                                       “if-then-else”




Friday, April 5, 13
(* Note:

           hd(list) takes the first element of list

           tl(list) takes all other elements of list

           *)



           fun sum(numbers) =

                      if numbers = [] then 0

                      else hd(numbers) + sum(tl(numbers))




Friday, April 5, 13
Friday, April 5, 13
So maybe you’re not convinced...


                      Let’s try an example that’s even more
                      interesting with pattern matching.




Friday, April 5, 13
Who knows FizzBuzz?



Friday, April 5, 13
// `~` in Rust is for allocating memory

        fn main() {
            for int::range(1, 101) |num| {
                io::println(
                    match (num % 3, num % 5) {
                        (0, 0) => ~"FizzBuzz", // must come first
                        (0, _) => ~"Fizz",
                        (_, 0) => ~"Buzz",
                        (_, _) => int::str(num) // must come last
                    }
                );
            }
        }

        // Source: Lindsey Kuper’s FizzBuzz revisited (http://composition.al/blog/2013/03/02/
        fizzbuzz-revisited/)




Friday, April 5, 13
The real heart of the function:

                      match (num %   3, num % 5) {
                         (0, 0) =>   ~"FizzBuzz", // must come first
                         (0, _) =>   ~"Fizz",
                         (_, 0) =>   ~"Buzz",
                         (_, _) =>   int::str(num) // must come last
                      }




Friday, April 5, 13
That’s nice and all, but there’s more...




Friday, April 5, 13
Both SML and Rust are strongly typed,
                      and they let us define our own types.


                      We can then match against those types.




Friday, April 5, 13
enum Remainder {
                            zero,
                            other(NonZeroRem)
                      }

                      enum NonZeroRemainder {
                          one, two, three, four
                      }




Friday, April 5, 13
fn int_to_rem(num: int) -> Remainder
                          {
                            match num {
                                0 => zero,
                                1 => other(one),
                                2 => other(two),
                                3 => other(three),
                                4 => other(four),
                                _ => fail
                            }
                      }




Friday, April 5, 13
fn main() {
                      for int::range(1, 101) |num| {
                        io::println(
                           match (int_to_rem(num % 3), int_to_rem(num % 5)) {
                           (other(_), other(_)) => int::str(num),
                           (zero, other(_)) => ~"Fizz",
                           (other(_), zero) => ~"Buzz",
                           (zero, zero) => ~"FizzBuzz"
                        }
                        );
                      }
                  }




Friday, April 5, 13
Again the heart of the function:

             match (int_to_rem(num % 3), int_to_rem(num % 5)) {
                (other(_), other(_)) => int::str(num),
                (zero, other(_)) => ~"Fizz",
                (other(_), zero) => ~"Buzz",
                (zero, zero) => ~"FizzBuzz"
                      }




Friday, April 5, 13
Pattern Matching is powerful.


                      It allows us to easily change FizzBuzz




Friday, April 5, 13
match (int_to_rem(num % 3), int_to_rem(num % 5)) {
                         (other(two), other(one)) => ~"Zot",
                         (other(x), other(y)) => int::str(x/y),
                         (zero, other(_)) => ~"Fizz",
                         (other(x), zero) => ~"Buzz" + int::str(x),
                         (zero, zero) => ~"FizzBuzz"
                       }




Friday, April 5, 13
Friday, April 5, 13
So how about Pattern Matching in Ruby?




Friday, April 5, 13
pattern-match
                      github.com/k-tsj/pattern-match




Friday, April 5, 13
require 'pattern-match'

                match(object) do
                  with(pattern) do
                    ...
                  end
                  with(pattern) do
                    ...
                  end
                  ...
                end

                # patterns are binded variables
                available in block
Friday, April 5, 13
x = match(0) do
                        with(String) { “It’s a String!” }
                        with(Fixnum) { “It’s a Fixnum!” }
                      end

                      print x #=> “It’s a Fixnum!”




Friday, April 5, 13
require 'pattern-match'



                      1.upto(100) do |n|

                            match([(n % 3),(n % 5)]) do

                              with(_[0,0]) { puts "FizzBuzz" }

                              with(_[0,_]) { puts "Fizz" }

                              with(_[_,0]) { puts "Buzz" }

                              with(_[_,_]) { puts n }

                        end

                      end



Friday, April 5, 13
It allows for some cool things!




Friday, April 5, 13
require 'pattern-match'



           match([1, "2", 3.0, "four"]) do

                      with(_[a & 1, b & Or(Float, String), c & Not(Fixnum), d])

                      with(_[a & Fixnum, b & Not(String), c, d & Not(“four”)])

                 end

           end




Friday, April 5, 13
Friday, April 5, 13

More Related Content

Featured

PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...DevGAMM Conference
 

Featured (20)

Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
 

Feeling Objects: Pattern Matching in Ruby

  • 2. Feel Objects Pattern Matching in Ruby Friday, April 5, 13
  • 7. What the hell is pattern matching and why should I care? Friday, April 5, 13
  • 8. Wikipedia Definition “...the act of checking a perceived sequence of tokens for the presence of the constituents of some pattern.” Friday, April 5, 13
  • 10. My Best Try Checking a data type against some predefined patterns, and when that data type matches one of the predefined patterns, do something. Friday, April 5, 13
  • 11. In Short... Pattern matching is another way to do control flow. Friday, April 5, 13
  • 15. fun sum(numbers) = case numbers of [] => 0 x::xs => x + sum(xs) Friday, April 5, 13
  • 16. I don’t know SML. What the hell is this? Friday, April 5, 13
  • 17. Function declaration fun sum(numbers) = case numbers of [] => 0 x::xs => x + sum(xs) Friday, April 5, 13
  • 18. Case statement matching against the list “numbers”. fun sum(numbers) = case numbers of [] => 0 x::xs => x + sum(xs) Friday, April 5, 13
  • 19. First pattern fun sum(numbers) = case numbers of [] => 0 x::xs => x + sum(xs) Friday, April 5, 13
  • 20. Second pattern fun sum(numbers) = case numbers of [] => 0 x::xs => x + sum(xs) Friday, April 5, 13
  • 21. So let’s call it! Friday, April 5, 13
  • 22. val numbers = [1, 6, 8] sum(numbers) Friday, April 5, 13
  • 23. sum([1, 6, 8]) = case numbers of [] => 0 x::xs => x + sum(xs) Friday, April 5, 13
  • 24. What pattern does numbers match? Friday, April 5, 13
  • 25. x::xs => x + sum(xs) 1::[6, 8] => 1 + sum([6, 8]) Friday, April 5, 13
  • 26. x::xs => x + sum(xs) 6::[8] => 1 + 6 + sum([8]) Friday, April 5, 13
  • 27. x::xs => x + sum(xs) 8::[] => 1 + 6 + 8 + sum([]) Friday, April 5, 13
  • 28. sum([]) = case numbers of [] => 0 x::xs => x + sum(xs) Friday, April 5, 13
  • 29. What pattern does numbers match? Friday, April 5, 13
  • 30. [] => 1 + 6 + 8 + 0 15 Friday, April 5, 13
  • 31. Pretty easy, and could be implemented in roughly the same amount of characters with “if-then-else” Friday, April 5, 13
  • 32. (* Note: hd(list) takes the first element of list tl(list) takes all other elements of list *) fun sum(numbers) = if numbers = [] then 0 else hd(numbers) + sum(tl(numbers)) Friday, April 5, 13
  • 34. So maybe you’re not convinced... Let’s try an example that’s even more interesting with pattern matching. Friday, April 5, 13
  • 36. // `~` in Rust is for allocating memory fn main() { for int::range(1, 101) |num| { io::println( match (num % 3, num % 5) { (0, 0) => ~"FizzBuzz", // must come first (0, _) => ~"Fizz", (_, 0) => ~"Buzz", (_, _) => int::str(num) // must come last } ); } } // Source: Lindsey Kuper’s FizzBuzz revisited (http://composition.al/blog/2013/03/02/ fizzbuzz-revisited/) Friday, April 5, 13
  • 37. The real heart of the function: match (num % 3, num % 5) { (0, 0) => ~"FizzBuzz", // must come first (0, _) => ~"Fizz", (_, 0) => ~"Buzz", (_, _) => int::str(num) // must come last } Friday, April 5, 13
  • 38. That’s nice and all, but there’s more... Friday, April 5, 13
  • 39. Both SML and Rust are strongly typed, and they let us define our own types. We can then match against those types. Friday, April 5, 13
  • 40. enum Remainder { zero, other(NonZeroRem) } enum NonZeroRemainder { one, two, three, four } Friday, April 5, 13
  • 41. fn int_to_rem(num: int) -> Remainder { match num { 0 => zero, 1 => other(one), 2 => other(two), 3 => other(three), 4 => other(four), _ => fail } } Friday, April 5, 13
  • 42. fn main() { for int::range(1, 101) |num| { io::println( match (int_to_rem(num % 3), int_to_rem(num % 5)) { (other(_), other(_)) => int::str(num), (zero, other(_)) => ~"Fizz", (other(_), zero) => ~"Buzz", (zero, zero) => ~"FizzBuzz" } ); } } Friday, April 5, 13
  • 43. Again the heart of the function: match (int_to_rem(num % 3), int_to_rem(num % 5)) { (other(_), other(_)) => int::str(num), (zero, other(_)) => ~"Fizz", (other(_), zero) => ~"Buzz", (zero, zero) => ~"FizzBuzz" } Friday, April 5, 13
  • 44. Pattern Matching is powerful. It allows us to easily change FizzBuzz Friday, April 5, 13
  • 45. match (int_to_rem(num % 3), int_to_rem(num % 5)) { (other(two), other(one)) => ~"Zot", (other(x), other(y)) => int::str(x/y), (zero, other(_)) => ~"Fizz", (other(x), zero) => ~"Buzz" + int::str(x), (zero, zero) => ~"FizzBuzz" } Friday, April 5, 13
  • 47. So how about Pattern Matching in Ruby? Friday, April 5, 13
  • 48. pattern-match github.com/k-tsj/pattern-match Friday, April 5, 13
  • 49. require 'pattern-match' match(object) do with(pattern) do ... end with(pattern) do ... end ... end # patterns are binded variables available in block Friday, April 5, 13
  • 50. x = match(0) do with(String) { “It’s a String!” } with(Fixnum) { “It’s a Fixnum!” } end print x #=> “It’s a Fixnum!” Friday, April 5, 13
  • 51. require 'pattern-match' 1.upto(100) do |n| match([(n % 3),(n % 5)]) do with(_[0,0]) { puts "FizzBuzz" } with(_[0,_]) { puts "Fizz" } with(_[_,0]) { puts "Buzz" } with(_[_,_]) { puts n } end end Friday, April 5, 13
  • 52. It allows for some cool things! Friday, April 5, 13
  • 53. require 'pattern-match' match([1, "2", 3.0, "four"]) do with(_[a & 1, b & Or(Float, String), c & Not(Fixnum), d]) with(_[a & Fixnum, b & Not(String), c, d & Not(“four”)]) end end Friday, April 5, 13