CS61A Lecture 21: Generic Functions

5 Pages
Unlock Document

University of California - Berkeley
Computer Science
De Nero

Generic Functions of Multiple Arguments A function might want to operate on multiple data types Last time: Polymorphic functions using message passing Interfaces: collections of messages that have specific behavior conditions Two interchangeable implementations of complex numbers Today: An arithmetic system over related types Type dispatching Data-directed programming Type coercion What’s different? Today’s generic functions apply to multiple arguments that don’t share common interface Representing Numbers Rational numbers represented as a numerator and denominator class Rational: """A rational number represented as a numerator and denominator. All rational numbers are represented in lowest terms. >>> Rational(6, 4) Rational(3, 2) >>> add_rational(Rational(3, 14), Rational(2, 7)) Rational(1, 2) >>> mul_rational(Rational(7, 10), Rational(2, 7)) Rational(1, 5) """ def __init__(self, numer, denom): g = gcd(numer, denom) self.numer = numer // g self.denom = denom // g def __repr__(self): return 'Rational({0}, {1})'.format(self.numer, self.denom) def __str__(self): return '{0}/{1}'.format(self.numer, self.denom) def __add__(self, other): return add_rational(self, other) def __mul__(self, other): return mul_rational(self, other) Complex Numbers: the Rectangular Representation Special Methods for Arithmetic Adding instance sod user-defined classes with __add__. def __add__ (self, other): return add_rational(self, other) We can also __add__ complex numbers, even with multiple representations Also __mul__ complex numbers Can use normal operators + and * instead of writing mul_complex or add_complex Composition better Can also use dot expression Type Dispatching Data abstraction and class definitions keep types separate Some operations need cross type boundaries Define a different function for each possible combination of types for which an operation (e.g. addition) is valid def complex(z): return type(z) in (ComplexRI, ComplexMA) def rational(z): return type(z) is Rational def add_complex_and_rational(z, r): return ComplexRI(z.real + r.numer/r.denom, z.imag) def add_dispatching(z1, z2): """Add z1 and z2, which may be complex or rational. >>> add_dispatching(ComplexRI(1.5, 0), Rational(3, 2)) ComplexRI(3.0, 0) >>> add_dispatching(Rational(5, 3), Rational(1, 2)) Rational(13, 6) """ if complex(z1) and complex(z2): return add_complex(z1, z2) elif complex(z1) and rational(z2): return add_complex_and_rational(z1, z2) elif rational(z1) and complex(z2): return add_complex_and_rational(z2, z1) else: return add_rational(z1, z2) Tag-Based Type-dispatching Idea: Use a dictionary to dispatch on pairs of types def type_tag(x): """Return the tag associated with the type of x.""" return type_tags[type(x)] type_tags = {ComplexRI: 'com', ComplexMA: 'com', Rational: 'rat'} def add(z1, z2): """Add z1 and z2, which may be complex or rational. >>> add(ComplexRI(1.5, 0), Rational(3, 2)) ComplexRI(3.0, 0) >>> add(Rational(5, 3), Rational(1, 2)) Rational(13, 6) """
More Less

Related notes for COMPSCI 61A

Log In


Don't have an account?

Join OneClass

Access over 10 million pages of study
documents for 1.3 million courses.

Sign up

Join to view


By registering, I agree to the Terms and Privacy Policies
Already have an account?
Just a few more details

So we can recommend you notes for your school.

Reset Password

Please enter below the email address you registered with and we will send you a link to reset your password.

Add your courses

Get notes from the top students in your class.