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
570
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
710
The Value of Being Lazy
sferik
3
790
Ruby Trivia 2
sferik
0
770
Ruby Trivia
sferik
2
1.3k
💀 Symbols
sferik
5
1.9k
Content Negotiation for REST APIs
sferik
8
1k
Writing Fast Ruby
sferik
628
62k
Mutation Testing with Mutant
sferik
5
1.1k
Other Decks in Programming
See All in Programming
testingを眺める
matumoto
1
140
複雑なドメインに挑む.pdf
yukisakai1225
5
1.2k
基礎から学ぶ大画面対応(Learning Large-Screen Support from the Ground Up)
tomoya0x00
0
1.5k
Performance for Conversion! 分散トレーシングでボトルネックを 特定せよ
inetand
0
860
モバイルアプリからWebへの横展開を加速した話_Claude_Code_実践術.pdf
kazuyasakamoto
0
330
How Android Uses Data Structures Behind The Scenes
l2hyunwoo
0
460
Improving my own Ruby thereafter
sisshiki1969
1
160
JSONataを使ってみよう Step Functionsが楽しくなる実践テクニック #devio2025
dafujii
1
530
Vue・React マルチプロダクト開発を支える Vite
andpad
0
110
@Environment(\.keyPath)那么好我不允许你们不知道! / atEnvironment keyPath is so good and you should know it!
lovee
0
120
チームのテスト力を鍛える
goyoki
2
170
「手軽で便利」に潜む罠。 Popover API を WCAG 2.2の視点で安全に使うには
taitotnk
0
860
Featured
See All Featured
KATA
mclloyd
32
14k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
36
2.5k
Designing for humans not robots
tammielis
253
25k
The World Runs on Bad Software
bkeepers
PRO
70
11k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
580
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
The Art of Programming - Codeland 2020
erikaheidi
56
13k
The Cost Of JavaScript in 2023
addyosmani
53
8.9k
Reflections from 52 weeks, 52 projects
jeffersonlam
352
21k
How STYLIGHT went responsive
nonsquared
100
5.8k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
840
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