Gordon Bell observed: The cheapest, fastest and most reliable components of a computer system are those that aren't there. This has a parallel in data.

Slides:



Advertisements
Similar presentations
Python Objects and Classes
Advertisements

Lists in Lisp and Scheme a. Lists are Lisp’s fundamental data structures, but there are others – Arrays, characters, strings, etc. – Common Lisp has moved.
CSE341: Programming Languages Lecture 15 Mutation, Pairs, Thunks, Laziness, Streams, Memoization Dan Grossman Fall 2011.
COMPSCI 105 S Principles of Computer Science Linked Lists 2.
6.001 SICP 1 Normal (Lazy) Order Evaluation Memoization Streams.
Tail Recursion. Problems with Recursion Recursion is generally favored over iteration in Scheme and many other languages – It’s elegant, minimal, can.
CMPT 120 Lists and Strings Summer 2012 Instructor: Hassan Khosravi.
Methods in Computational Linguistics II Queens College Lecture 7: Structuring Things.
Python: Classes By Matt Wufsus. Scopes and Namespaces A namespace is a mapping from names to objects. ◦Examples: the set of built-in names, such as the.
Introduction to Pyrex September 2002 Brian Quinlan
By: Chris Harvey Python Classes. Namespaces A mapping from names to objects Different namespaces have different mappings Namespaces have varying lifetimes.
Functional Programming With examples in F#. Pure Functional Programming Functional programming involves evaluating expressions rather than executing commands.
Iterators, Linked Lists, MapReduce, Dictionaries, and List Comprehensions... OH MY! Special thanks to Scott Shawcroft, Ryan Tucker, and Paul Beck for their.
Python iterators and generators. Iterators and generators  Python makes good use of iterators  And has a special kind of generator function that is.
Iterators and Generators Thomas Wouters XS4ALL
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
Today… Python Keywords. Iteration (or “Loops”!) Winter 2016CISC101 - Prof. McLeod1.
Introduction to Python memory management. Find the slides at: manuelschipper.com/slides.pdf.
Rajkumar Jayachandran.  Classes for python are not much different than those of other languages  Not much new syntax or semantics  Python classes are.
CSE 341 Lecture 21 delayed evaluation; thunks; streams slides created by Marty Stepp
LECTURE 10 Semantic Analysis. REVIEW So far, we’ve covered the following: Compilation methods: compilation vs. interpretation. The overall compilation.
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Spring 2017.
Algorithmic complexity: Speed of algorithms
6.001 SICP Variations on a Scheme
Topics Introduction to Repetition Structures
Copyright (c) 2017 by Dr. E. Horvath
CSE 341 Lecture 20 Mutation; memoization slides created by Marty Stepp
Lists in Lisp and Scheme
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Winter 2013.
Topics Introduction to Repetition Structures
Arrays in C.
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Zach Tatlock Winter 2018.
CMSC 341 Lecture 10 B-Trees Based on slides from Dr. Katherine Gibson.
Writing Functions( ) (Part 5)
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Spring 2013.
Python Primer 2: Functions and Control Flow
Variables, Environments and Closures
CISC101 Reminders Quiz 1 grading underway Assn 1 due Today, 9pm.
CISC101 Reminders Slides have changed from those posted last night…
The Metacircular Evaluator
FP Foundations, Scheme In Text: Chapter 14.
CISC101 Reminders Assn 3 due tomorrow, 7pm.
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Spring 2016.
Data Abstraction UW CSE 160 Spring 2018.
Python iterators and generators
Dynamic Scoping Lazy Evaluation
Closure Closure binds a first-class function and a lexical environment together This is a complex topic, so we will build up our understanding of it we.
CSE373: Data Structures & Algorithms Lecture 5: AVL Trees
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Autumn 2017.
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Autumn 2018.
Winter 2018 With thanks to: Dan Grossman / Eric Mullen
Python Tutorial for C Programmer Boontee Kruatrachue Kritawan Siriboon
Algorithmic complexity: Speed of algorithms
6.001 SICP Streams – the lazy way
6.001 SICP Further Variations on a Scheme
Streams, Delayed Evaluation and a Normal Order Interpreter
Streams and Lazy Evaluation in Lisp and Scheme
(more) Python.
CISC101 Reminders All assignments are now posted.
Dan Grossman / Eric Mullen Autumn 2017
CISC101 Reminders Assignment 2 due today.
Algorithmic complexity: Speed of algorithms
Data Structures & Algorithms
Topics Introduction to Repetition Structures
OPERATING SYSTEMS DEADLOCKS.
Tree A tree is a data structure in which each node is comprised of some data as well as node pointers to child nodes
Brett Wortzman Summer 2019 Slides originally created by Dan Grossman
CSE341: Programming Languages Lecture 14 Thunks, Laziness, Streams, Memoization Dan Grossman Spring 2019.
Data Abstraction UW CSE 160.
Python iterators and generators
Presentation transcript:

Gordon Bell observed: The cheapest, fastest and most reliable components of a computer system are those that aren't there. This has a parallel in data structures: The fastest, most parsimonious, and best performing data structure is one which is never concretized. A promise to create data when–or if–it is needed is often easy to make. PyCon 2010: Maximize your program's laziness David Mertz

Gordon Bell observed: The cheapest, fastest and most reliable components of a computer system are those that aren't there. This has a parallel in data structures: The fastest, most parsimonious, and best performing data structure is one which is never concretized. A promise to create data when–or if–it is needed is often easy to make. PyCon 2010: Maximize your program's laziness David Mertz

The addition of iterators and generators to Python during the 2.x series, and their more systematic use in 3.x, provides an easy way to work with lazy computation. Using these facilities well can improve program performance, often their big-O complexity. Complex lazy data structures may require special design in order to encapsulate more complex promises than one can make with list-like iterators. PyCon 2010: Maximize your program's laziness David Mertz

The addition of iterators and generators to Python during the 2.x series, and their more systematic use in 3.x, provides an easy way to work with lazy computation. Using these facilities well can improve program performance, often their big-O complexity. Complex lazy data structures may require special design in order to encapsulate more complex promises than one can make with list-like iterators. PyCon 2010: Maximize your program's laziness David Mertz

The addition of iterators and generators to Python during the 2.x series, and their more systematic use in 3.x, provides an easy way to work with lazy computation. Using these facilities well can improve program performance, often their big-O complexity. Complex lazy data structures may require special design in order to encapsulate more complex promises than one can make with list-like iterators. PyCon 2010: Maximize your program's laziness David Mertz

Review of laziness Examples from Functional Programming Languages Generic any language laziness Iterators and the itertools module Generators and generator expressions Memoization and the weakref module Laziness in a directed acyclic graph Miscellaneous exoterica (but not necessarily in the order listed)

Laziness in a really lazy language (Haskell) module Bounce where bounce :: Int -> Int bounce n = (n* ) `mod` bseq :: Int -> [Int] bseq init = bounce init : map bounce (bseq init) Bounce> take 8 (bseq 1) [901,42001,18901,64001,56901,66001,14901,48001] Bounce> bseq 1 !! PyCon 2010: Maximize your program's laziness David Mertz (imagine Bounce as a really crude stand-in for, e.g. cipher-block chaining)

Laziness by declaration of promises (Scheme) > (define (bounce n) (modulo (+ (* n 379) 522) )) > (define (bseq n) (let ((next (bounce n))) (cons next (delay (bseq next))))) > (display (car (bseq 1))) 901 > (display (cdr (bseq 1))) # > (display (force (cdr (bseq 1)))) ( # ) PyCon 2010: Maximize your program's laziness David Mertz

Iterators and Generators (remember 2001?) Iterators and generators are “sequence-like” Potentially infinite length Only need to concretize one element at a time Hence cannot slice or index (but wait a few slides) An iterator is an object that has the methods.next() and.__iter__(). That's all! A generator is a powerful type of iterator: a resumable function! Not quite a continuation, but more than a closure

PyCon 2010: Maximize your program's laziness David Mertz Iterators and Generators: An iterator example class Iterator(object): def __init__(self, init=1, stop=None): self.n, self.stop = init, stop def next(self): if self.n == self.stop: raise StopIteration self.n = (self.n* ) % return self.n def __iter__(self): return self (remember that this is our crude stand-in for something expensive)

PyCon 2010: Maximize your program's laziness David Mertz Iterators and Generators: A generator example def generator(init=1, stop=None): n = init while n != stop: n = (n* ) % yield n >>> for n in generator(): # for n in Iterator():... if not something_about(n):... break... do_stuff(n) # return n w/ side effect

PyCon 2010: Maximize your program's laziness David Mertz Iterators and Generators: itertools module 1 >>> while n in generator():... if not something_about(n): break... do_stuff(n) # return n w/ side effect >>> from itertools import * >>> ready = imap(do_stuff, takewhile(... something_about, generator())) >>> ready >>> list(ready) # for n in ready: print n, [901, 42001, 18901, 64001, 56901, 66001, 14901, 48001]

PyCon 2010: Maximize your program's laziness David Mertz Iterators and Generators: itertools module 2 >>> from itertools import * >>> slice50_55 = islice(generator(), 50, 55) >>> slice50_55 >>> list(slice50_55) [50901, 92001, 68901, 14001, 6901] >>> list(slice50_55) [] >>> g = generator(); list(islice(g, 3)) (what do we expect g to do if we keep islice()'ing it?)

PyCon 2010: Maximize your program's laziness David Mertz Iterators and Generators: generator expressions # Cannot use listcomp on infinite generator # E.g. [n**2 for n in generator() if n%3] blows up! >>> not_div3 = (n**2 for n in generator() if n % 3) >>> not_div3 at 0x21bab70> >>> from itertools import * >>> list(islice(not_div3, 3, 6)) [ L, L, L]

PyCon 2010: Maximize your program's laziness David Mertz Things to avoid doing (… at this particular moment): Expensive computations Concretize large data sets Time consuming background operations Database queries Retrieving network resources Waiting for external events (but the last one is the topic of some different presentation)

PyCon 2010: Maximize your program's laziness David Mertz A minimal class for delaying expensive actions 1 class Promise(object): def __init__(self, func, *args, **kws): self.func = func self.args = args self.kws = kws def __call__(self): if not hasattr(self, 'val'): self.val = self.func(*self.args,**self.kws) return self.val

PyCon 2010: Maximize your program's laziness David Mertz A minimal class for delaying expensive actions 2 >>> from promises import * >>> p = Promise(slow_random) >>> p >>> p.val AttributeError: 'Promise' object has no attribute 'val' >>> p()# Eventually get the result >>> p()# Immediately get the result

PyCon 2010: Maximize your program's laziness David Mertz A slightly friendlier class for making promises class Promise2(Promise): def forget(self): del self.val def __repr__(self): return repr(self()) def __iter__(self): return iter(self()) #...Some more magic methods could help too (now we can concretize with print val or for x in val)

PyCon 2010: Maximize your program's laziness David Mertz Seamless promises inside data structures class LazyDict(dict): def __getitem__(self, key): val = dict.__getitem__(self, key) if isinstance(val, Promise): val = val() return val >>> ld = LazyDict(p=Promise(slow_random), n=99) >>> print ld, ld['p'] {'p':, 'n':99}

PyCon 2010: Maximize your program's laziness David Mertz Making promises forgetfully to save memory 1 import weakref class WeakPromise(Promise): def __call__(self): if not hasattr(self, 'val'): val = self.func(*self.args, **self.kws) try: self.val = weakref.ref(val) except TypeError: self.val = val return self.val() (notice weakref can only reference object, not int, str, etc.)

PyCon 2010: Maximize your program's laziness David Mertz Making promises forgetfully to save memory 2 >>> wp = WeakPromise(module.func, arg1, arg2) >>> result = wp() >>> print result >>> print wp() >>> del result >>> print wp() None (if we want WeakPromise fulfilled anew, del wp.val)

PyCon 2010: Maximize your program's laziness David Mertz Trading memory for computation (memoization) def memoize(fn): class Cached(object): def __init__(self, fn): self.fn, self.cache = fn, dict() def __call__(self, *args, **kws): key = (repr(args), repr(kws)) self.cache[key] = self.cache.get(key) \ or self.fn(*args, **kws) return self.cache[key] return Cached(fn) (the twin of a Promise; compute right away, but only once)

PyCon 2010: Maximize your program's laziness David Mertz Promises in a directed acyclic graph. Each node has a value that is expensive to calculate and that depends on its parents. (A node holds a Promise, and pointers to parents and children) A B E D C F G >>> create_graph('A->C; A->E; B->C;...') Promised Invalidated Concretized Invalidated

PyCon 2010: Maximize your program's laziness David Mertz Promises in a directed acyclic graph. When a node is queried, its ancestors must be concretized. A B E D C F G >>> query_value('G') (A Promise is fulfilled by gaining a val attribute) Promised Invalidated Concretized Invalidated

PyCon 2010: Maximize your program's laziness David Mertz Promises in a directed acyclic graph. Changing the value of a node invalidates its descendants. A B E D C F G >>> set_value('C') (An invalid Promise might simply delete its val attribute) G E Promised Invalidated Concretized Invalidated

PyCon 2010: Maximize your program's laziness David Mertz Promises in a directed acyclic graph. Changing the shape of a graph might invalidate nodes. A B E D C F G >>> disconnect('C->E'); connect('E->F; C->D') (Notice that D was unfulfilled, hence has no value to invalidate) E G F Promised Invalidated Concretized Invalidated

PyCon 2010: Maximize your program's laziness David Mertz Promises in a directed acyclic graph. Queries fulfill anew the previously invalidated promises of ancestors. A B E D C F G >>> query_value('F') G Promised Invalidated Concretized Invalidated Promised Invalidated Concretized Invalidated

PyCon 2010: Maximize your program's laziness David Mertz Wrap-up / Questions? Review of laziness Examples from Functional Programming Languages Generic any language laziness Iterators and the itertools module Generators and generator expressions Memoization and the weakref module Laziness in a directed acyclic graph