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
540
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
680
The Value of Being Lazy
sferik
3
740
Ruby Trivia 2
sferik
0
720
Ruby Trivia
sferik
2
1.3k
💀 Symbols
sferik
5
1.8k
Content Negotiation for REST APIs
sferik
8
960
Writing Fast Ruby
sferik
628
61k
Mutation Testing with Mutant
sferik
5
1.1k
Other Decks in Programming
See All in Programming
Defying Front-End Inertia: Inertia.js on Rails
skryukov
0
360
Go1.24で testing.B.Loopが爆誕
kuro_kurorrr
0
170
snacks.nvim内のセットアップ不要なプラグインを紹介 / introduce_snacks_nvim
uhooi
0
360
Windows版PHPのビルド手順とPHP 8.4における変更点
matsuo_atsushi
0
380
Coding Experience Cpp vs Csharp - meetup app osaka@9
harukasao
0
530
コンテナでLambdaをデプロイするときに知っておきたかったこと
_takahash
0
160
新卒から4年間、20年もののWebサービスと 向き合って学んだソフトウェア考古学
oguri
8
7k
プログラミング教育のコスパの話
superkinoko
0
130
PHPでお金を扱う時、終わりのない 謎の1円調査の旅にでなくて済む方法
nakka
4
1.4k
Devin入門と最近のアップデートから見るDevinの進化 / Introduction to Devin and the Evolution of Devin as Seen in Recent Update
rkaga
8
4.1k
いまさら聞けない生成AI入門: 「生成AIを高速キャッチアップ」
soh9834
14
4k
英語文法から学ぶ、クリーンな設計の秘訣
newnomad
1
280
Featured
See All Featured
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
Optimising Largest Contentful Paint
csswizardry
35
3.2k
Testing 201, or: Great Expectations
jmmastey
42
7.4k
Agile that works and the tools we love
rasmusluckow
328
21k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.3k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
A better future with KSS
kneath
238
17k
Facilitating Awesome Meetings
lara
53
6.3k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Designing Experiences People Love
moore
141
23k
What's in a price? How to price your products and services
michaelherold
245
12k
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