Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Enumerator::Lazy
Search
Erik Berlin
August 02, 2016
Programming
1
400
Enumerator::Lazy
Presented at SF.rb on August 2, 2016.
Erik Berlin
August 02, 2016
Tweet
Share
More Decks by Erik Berlin
See All by Erik Berlin
Ruby Trivia 3
sferik
0
560
The Value of Being Lazy
sferik
3
600
Ruby Trivia 2
sferik
0
620
Ruby Trivia
sferik
2
1.1k
💀 Symbols
sferik
5
1.6k
Content Negotiation for REST APIs
sferik
8
830
Writing Fast Ruby
sferik
622
60k
Mutation Testing with Mutant
sferik
5
1k
Other Decks in Programming
See All in Programming
mb_trim関数を作りました
youkidearitai
PRO
1
240
RuboCop: LSP and Prism
koic
1
110
slog登場に伴うloggerの取り回し手法の見直し / kamakura.go #6
arthur1
0
160
TypeScriptコードの漸進的改善 / Progressive Improvement of TypeScript Code
medley
1
460
RailsConf 2024: Riffing on Rails: sketch your way to better designed code
kaspth
1
220
Namespace, What and Why
tagomoris
4
770
Amazon Aurora Serverless v2が意外と高かった話と、AWS Database Migration Serviceの話
satoshi256kbyte
1
110
Open standards for building event-driven applications in the cloud
meteatamel
0
230
Adding Security to Microcontroller Ruby
sylph01
1
170
RubyGems on ruby.wasm
kateinoigakukun
0
150
[RubyKaigi 2024] Ruby Mixology 101: adding shots of PHP, Elixir, and more
palkan
0
140
JavaScript Closure
asoluka
0
2k
Featured
See All Featured
Creatively Recalculating Your Daily Design Routine
revolveconf
211
11k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
12
1.1k
Optimising Largest Contentful Paint
csswizardry
13
2.4k
What the flash - Photography Introduction
edds
64
11k
Why Our Code Smells
bkeepers
PRO
331
56k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
126
32k
Typedesign – Prime Four
hannesfritz
36
2.1k
The Mythical Team-Month
searls
217
42k
How GitHub Uses GitHub to Build GitHub
holman
468
290k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
228
16k
How to Ace a Technical Interview
jacobian
273
22k
What's new in Ruby 2.0
geeforr
338
31k
Transcript
Enumerator::Lazy Erik Michaels-Ober @sferik
Imperative languages do iteration like this: int sum = 0;
for(i = 1; i < 10; i = i + 1) { sum = sum + i; }
Functional languages do iteration like this: rec_sum [] = 0
rec_sum (x:xs) = x + rec_sum xs rec_sum [1..9]
Object oriented languages (should) do iteration like this: sum =
0 (1..9).each do |i| sum += i end
Object oriented languages (should) do iteration like this: sum =
(1..9).inject(&:+)
Iterators Introduced in CLU by Barbara Liskov (1975) Copied in
Ruby by Yukihiro Matsumoto (1995)
Ruby’s iterator is called Enumerator
enum = Enumerator.new do |yielder| yielder.yield("sf") yielder.yield("dot") yielder.yield("rb") end
["sf", "dot", "rb"].each ["sf", "dot", "rb"].to_enum Enumerator.new(["sf", "dot", "rb"])
enum = Enumerator.new do |yielder| n = 0 loop do
yielder.yield(n) n += 1 end end
fib = Enumerator.new do |yielder| a = b = 1
loop do yielder.yield(a) a, b = b, a + b end end
module Enumerable def lazy_map(&block) Enumerator.new do |yielder| return to_enum(__method__) unless
block_given? each do |n| yielder.yield(block.call(n)) end end end end
module Enumerable def lazy_select(&block) Enumerator.new do |yielder| return to_enum(__method__) unless
block_given? each do |n| yielder.yield(n) if block.call(n) end end end end
Ruby 2.0 introduced Enumerator::Lazy
What are the first five even perfect squares over a
thousand?
lazy_integers = (1..Float::INFINITY).lazy lazy_integers.collect { |x| x ** 2 }.
select { |x| x.even? }. reject { |x| x < 1000 }. first(5) #=> [1024, 1156, 1296, 1444, 1600]
What are the first five twin primes?
require "prime" lazy_primes = Prime.lazy lazy_primes.select { |x| (x -
2).prime? }. collect { |x| [x - 2, x] }. first(5) #=> [[3, 5], [5, 7], [11, 13], [17, 19], [29, 31]]
module Enumerable def repeat_after_first return to_enum(__method__) unless block_given? each.with_index do
|*val, index| index.zero? ? yield(*val) : 2.times { yield(*val) } end end end
require "prime" lazy_primes = Prime.lazy lazy_primes.repeat_after_first. each_slice(2). select { |x,
y| x + 2 == y }. first(5) #=> [[3, 5], [5, 7], [11, 13], [17, 19], [29, 31]]
When are the next five Friday the 13ths?
require "date" lazy_dates = (Date.today..Date.new(9999)).lazy lazy_dates.select { |d| d.day ==
13 }. select { |d| d.friday? }. first(10)
Detect whether a text file contains a string? (without reading
the entire file into memory)
lazy_file = File.readlines("/path/to/file").lazy lazy_file.detect { |x| x =~ /regexp/ }
Being lazy is efficient.
Being lazy is elegant.
None
Thank you