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
380
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
590
Ruby Trivia 2
sferik
0
610
Ruby Trivia
sferik
2
1.1k
💀 Symbols
sferik
5
1.6k
Content Negotiation for REST APIs
sferik
8
820
Writing Fast Ruby
sferik
621
60k
Mutation Testing with Mutant
sferik
5
990
Other Decks in Programming
See All in Programming
Anthropic Cookbook のおすすめレシピ
schroneko
7
920
2 週間で Twitter Bot を作ってみた
contour_gara
0
340
今、知っておきたい! 生成AIエージェントの世界
elith
3
350
スクラムガイドのスプリントレトロスペクティブを改めて読みかえしてみた / Re-reading the Sprint Retrospective Section in the Scrum Guide
mackey0225
3
410
新宿ダンジョンを可視化してみた
satoshi7190
2
250
ADRを一年運用してみた/adr_after_a_year
hanhan1978
7
2.4k
VSCodeでのDatabricks開発もお勧めしたい/I would also recommend Databricks development with VSCode.
kazumain
0
250
Code Reviews
bkuhlmann
4
890
0→1と1→10の狭間で Javaという技術選定を振り返る/Reflecting on the Decision to Choose Java Between Scaling from 0 to 1 and 1 to 10
jaguar_imo
2
380
Azure OpenAI Serviceのプロンプトエンジニアリング入門
tomokusaba
3
690
障害対応を起点としたもっといい開発と運用のサイクル作りのためにできること / Hatena Enginner Seminar #29
polamjag
0
110
What We Can Learn From OSS
inouehi
0
420
Featured
See All Featured
Bootstrapping a Software Product
garrettdimon
PRO
302
110k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
187
16k
Learning to Love Humans: Emotional Interface Design
aarron
267
39k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
352
28k
YesSQL, Process and Tooling at Scale
rocio
164
13k
Code Reviewing Like a Champion
maltzj
514
39k
Principles of Awesome APIs and How to Build Them.
keavy
121
16k
The Cult of Friendly URLs
andyhume
74
5.7k
Happy Clients
brianwarren
92
6.4k
Build The Right Thing And Hit Your Dates
maggiecrowley
24
2k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
227
16k
Art, The Web, and Tiny UX
lynnandtonic
289
19k
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