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
730
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Enumerator::Lazy
Presented at SF.rb on August 2, 2016.
Erik Berlin
August 02, 2016
More Decks by Erik Berlin
See All by Erik Berlin
Ruby Trivia 3
sferik
0
790
The Value of Being Lazy
sferik
3
890
Ruby Trivia 2
sferik
0
840
Ruby Trivia
sferik
2
1.4k
💀 Symbols
sferik
5
2k
Content Negotiation for REST APIs
sferik
8
1.1k
Writing Fast Ruby
sferik
630
63k
Mutation Testing with Mutant
sferik
5
1.2k
Other Decks in Programming
See All in Programming
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
190
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
500
仕様書を書く前にハーネスを作る - Agent Native開発は「探索を速く、判定を固く」
gotalab555
4
1.7k
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
180
運用ダッシュボードの設計を誰も教えてくれないのだけどみなさんどうしてるんですか? - チームに監視するという文化を根付かせるための第一歩を踏みたい -
satoshi256kbyte
1
130
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
210
VibeCodingからAgenticWorkflowへ
starfish719
0
600
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
560
【QA Test Talk Vol.8】AI-DLC による Whole Team Approach の加速
pkshadeck
PRO
0
200
Android CLI
fornewid
0
220
What's New in Android 2026
veronikapj
0
260
リアルな遅延を測る仕様
kota_yata
1
120
Featured
See All Featured
Navigating Weather and Climate Data
rabernat
0
480
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
710
Why Our Code Smells
bkeepers
PRO
340
58k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
240
How to Ace a Technical Interview
jacobian
281
24k
So, you think you're a good person
axbom
PRO
2
2.1k
Mobile First: as difficult as doing things right
swwweet
225
10k
Technical Leadership for Architectural Decision Making
baasie
3
490
First, design no harm
axbom
PRO
2
1.2k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
580
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