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
2
600
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
720
The Value of Being Lazy
sferik
3
820
Ruby Trivia 2
sferik
0
780
Ruby Trivia
sferik
2
1.3k
💀 Symbols
sferik
5
1.9k
Content Negotiation for REST APIs
sferik
8
1k
Writing Fast Ruby
sferik
630
62k
Mutation Testing with Mutant
sferik
5
1.1k
Other Decks in Programming
See All in Programming
仕様がそのままテストになる!Javaで始める振る舞い駆動開発
ohmori_yusuke
8
4.6k
乱雑なコードの整理から学ぶ設計の初歩
masuda220
PRO
32
14k
例外処理を理解して、設計段階からエラーを見つけやすく、起こりにくく #phpconfuk
kajitack
12
6.3k
GraalVM Native Image トラブルシューティング機能の最新状況(2025年版)
ntt_dsol_java
0
160
Eloquentを使ってどこまでコードの治安を保てるのか?を新人が考察してみた
itokoh0405
0
3.2k
Module Harmony
petamoriken
2
480
AIを駆使して新しい技術を効率的に理解する方法
nogu66
1
650
自動テストのアーキテクチャとその理由ー大規模ゲーム開発の場合ー
segadevtech
2
1k
JJUG CCC 2025 Fall: Virtual Thread Deep Dive
ternbusty
3
470
歴史から学ぶ「Why PHP?」 PHPを書く理由を改めて理解する / Learning from History: “Why PHP?” Rediscovering the Reasons for Writing PHP
seike460
PRO
0
160
詳細の決定を遅らせつつ実装を早くする
shimabox
1
1.3k
How Software Deployment tools have changed in the past 20 years
geshan
0
340
Featured
See All Featured
Unsuck your backbone
ammeep
671
58k
The Art of Programming - Codeland 2020
erikaheidi
56
14k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
Documentation Writing (for coders)
carmenintech
76
5.1k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
11
940
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.8k
Git: the NoSQL Database
bkeepers
PRO
432
66k
Fireside Chat
paigeccino
41
3.7k
Statistics for Hackers
jakevdp
799
230k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
Making the Leap to Tech Lead
cromwellryan
135
9.6k
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