Top Banner
More on Abstract Data Types Noah Mendelsohn Tufts University Email: [email protected] Web: http://www.cs.tufts.edu/~noah COMP 40: Machine Structure and Assembly Language Programming (Spring 2014)
36

More on Abstract Data Types Noah Mendelsohn Tufts University Email: [email protected]@cs.tufts.edu Web: noah COMP 40: Machine.

Jan 03, 2016

Download

Documents

Aldous Stanley
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

More on Abstract Data Types

Noah MendelsohnTufts UniversityEmail: [email protected]: http://www.cs.tufts.edu/~noah

COMP 40: Machine Structure and

Assembly Language Programming (Spring 2014)

Page 2: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Last time we covered

How data and pointers are stored in the computer’s memory

Abstraction, modularity, reuse, information hiding

The special role of void * and incomplete structures

Generalizing over values and types

2

Today Generalizing over computation

Function pointers

Iteration and mapping in a functional style

Boxed and unboxed data structures

Page 3: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Quick Review

Page 4: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Software structures model real world objects and concepts

Integers

Students

Bank statements

Photographic images

Sound recordings

Etc.

4

These things aren’t bits!!

They don’t live in computers, but…

Page 5: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Software structures model real world objects and concepts

Integers

Students

Bank statements

Photographic images

Sound recordings

Etc.

5

We build data structures that model them

The course materials refer to these is being in the “World of Ideas”

Page 6: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Key principles to watch for

Abstraction – Refers to the act of “pulling away from” something so that unimportant details

are hidden”1

Modularity & clean interfaces– Each module “does one thing well” 2

Information hiding– Modules keep details of their internals secret

Generalization– When practical, each module or service should be as generally useful as

possible

6

1 Prof. Mark Sheldon – COMP 11 Big Ideas 2 Ken Thompson, co-inventor of Unix – The Unix Philosophy

Page 7: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Interfaces

7

Inte

rface

ImplementationClient

E.g. your fgroups program

E.g. implementation ofHanson Table_T

E.g. methods in Hanson table.h

Page 8: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Interfaces

8

Inte

rface

ImplementationClient

Many different programs can re-use the interface and the implementation!

The implementation chooses a representation … NOT visible to the client

Page 9: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Interfaces

9

Inte

rface

ImplementationClient

E.g. your fgroups program

E.g. implementation ofHanson Table_T

E.g. methods in Hanson table.h

My_table = Table_new(… … …)

Q. What can Table_new return?

I will show you two ways of doing this

A. A pointer to data you can’t look at

You will use this pointer to identify the new table

Page 10: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Client doesn’t know secret implementation

10

Inte

rface

ImplementationClient

my_table = Table_new(… … …)

Struct Table_t { …data declartions…}

struct Table_T *table_ptr;

void *table_ptr;

Page 11: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Client doesn’t know secret implementation

12

Inte

rface

ImplementationClient

my_table = Table_new(… … …)

Struct Table_t { …data declartions…}

struct Table_T *table_ptr;

void *table_ptr;

Note: These declarations are in the declaration

(either in a table.c, or in a tableimp.h)

Page 12: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Hanson does this with incomplete structs

13

Inte

rface

ImplementationClient

my_table = Table_new(… … …)

Struct Table_t { …data declartions…}

struct Table_T *table_ptr;

struct Table_t *table_ptr;

Client has incomplete

declaration of the struct

Page 13: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

By the way, this is exactly what languages like C++ do

14

class Myclass { int some_method(int a) {…};}

Myclass my_object = new Myclass();

my_object -> some_method(5);

Under the covers, C++ implements this as:

my_object -> some_method(my_object, 5);

Page 14: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Generalization

Page 15: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

You’ve already seen some generalization

16

int square3() {

return 3*3;}

We don’t do this

int square(int n) {

return n*n;}

We do this!

Generalize over input value

Can we generalize over the type of information?

Page 16: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

We need to generalize over types

17

List_of_students_new(…);List_of_cars_new(…);List_of_bank_stmts_new(…);

We don’t want this

List_new(…);

We want this!

How do we declare the input to List_push()?(after all, its type could be anything)

Can we generalize over the type of information?

Page 17: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

How do we declare List_push?

18

void List_push(List_T list, void *x);

Hanson’s declaration for List_push

struct Car {char *brand; int weight};typedef struct Car Car;Car mycar = {“ford”, 2000};Car *retrieved_car;

mylist = List_list(NULL); /* create empty list */List_push(mylist, &mycar); /* put my car on the list */

Page 18: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Void * allows us to generalize over types

19

void List_push(List_T list, void *x);

Hanson’s declaration for List_push

The list will remember a pointer to anything.

struct Car {char *brand; int weight};typedef struct Car Car;Car mycar = {“ford”, 2000};Car *retrieved_car;

mylist = List_list(NULL); /* create empty list */List_push(mylist, &mycar); /* put my car on the list */

Any pointer can be passed to a void * parameter

Page 19: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Void * allows us to generalize over types

20

void List_push(List_T list, void *x);

Hanson’s declaration for List_push

struct Car {char *brand; int weight};typedef struct Car Car;Car mycar = {“ford”, 2000};Car *retrieved_car_p;

mylist = List_list(NULL); /* create empty list */List_push(mylist, &mycar); /* put my car on the list */

List_pop(mylist, &retrieved_car_p); /* get back mycar */

This generalization is known as universal polymorphism

Page 20: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Void * allows us to generalize over types

21

void List_push(List_T list, void *x);

Hanson’s declaration for List_push

struct Car {char *brand; int weight};typedef struct Car Car;Car mycar = {“ford”, 2000};Car *retrieved_car_p;

mylist = List_list(NULL); /* create empty list */List_push(mylist, &mycar); /* put my car on the list */

List_pop(mylist, &retrieved_car_p); /* get back mycar */

IMPORTANT:Retrieved_car_p is already a pointer. Why do we have to pass the address of retrieved_car_p?

Page 21: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Generalizing Over Computation

Page 22: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Why generalize over function?

We’ve already generalized types…sometimes we need different code to work on each type– Classic example: we’re building a sort routine that can sort anything…

– …the rules for sorting different types of things are different

Mapping: do the same operation on each entry in a collection

Providing or overriding behavior in a common implementation– Overriding default output format

– Overriding data source for some input routine

– Etc.

23

Page 23: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Function pointers in C

We know the code is living in memory

Can we take the address of code? Yes!

24

Syntax

int square(int n) {

return n*n;}

int (*somefunc)(int n);

somefunc = □printf(“3 squared is %d\n”, (*somefunc)(3));

Page 24: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Be sure you understand why this works!

25

int square(int n) {

return n*n;}

int cube(int n) {

return n*n*n;}

intmain(int argc, char *argv[]){

int (*somefunc)(int n);

somefunc = □printf("3 squared is %d\n", (*somefunc)(3));

somefunc = &cube;printf("3 cubed is %d\n", (*somefunc)(3));

return 0;}

Page 25: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Be sure you understand why this works!

26

int square(int n) {

return n*n;}

int cube(int n) {

return n*n*n;}

intmain(int argc, char *argv[]){

int (*somefunc)(int n);

somefunc = □printf("3 squared is %d\n", (somefunc)(3));

somefunc = &cube;printf("3 cubed is %d\n", (*somefunc)(3));

return 0;}

The “*” is optional…

…modern versions of C provide it for you if you leave it out.

Page 26: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Using function pointers

You’ve seen a simple example

We often pass function pointers as arguments to other functions

This allows us to generalize over function

Examples from Hanson:– cmp and hash routines for tables

– apply() functions for mapping

27

Page 27: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Computing on Collections

Page 28: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

One option: loops

29

/* NOT how Hanson usually does it */tab= Table_new(…):…add some data here..

for (i = 0, i < Table_length(arr) { upcase(Table_getnext(arr, NEXT));}

This is pseudo-code: some details just to show the idea.Hanson doesn’t do it this way anyway.

Page 29: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

The functional (Hanson) way

30

void upcasefunction(void *key, void **value, void *cl) { …can uppercase **value here..}

tab= Table_new(…):…add some data here..Table_map(tab, upcasefunction, ??);

Page 30: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

The functional (Hanson) way

31

void upcasefunction(void *key, void **value, void *cl) { …can uppercase **value here..}

tab= Table_new(…):…add some data here..Table_map(tab, upcasefunction, ??);

The map Table_map function loops calling upcasefunction repeatedly, once for each entry

Passing pointer to function

Page 31: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

The closure: shared data for the mapping

32

void upcasefunction(void *key, void **value, void *cl) { …can uppercase **value here..}struct cl mycl {…shared data here..};

tab= Table_new(…):…add some data here..Table_map(tab, upcasefunction, &mycl);

The data in mycl is passed in from the caller……can be seen and updated in upcasefunction

Page 32: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Mapping vs loops

Map advantages:– Clean, easy to reason about

– Often less code to write

– Automatically gets the iteration right (e.g. length)

Disadvantages– Less flexible: what if we want to iterate in unusual order?

– Less obvious how to iterate multiple structures at once (there are ways)

– Getting closures right can be tricky

Mapping is a classic functional programming construct

33

Page 33: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Unboxed DataGeneralizing to Collections of Objects that Aren’t Pointers

Page 34: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Boxed and unboxed collections

The collections you’ve seen so far are boxed List_push(mylist, &data); /* list stores a pointer */

Problem: we want an array of 1 million characters– A character is 1 byte

– A pointer to a character is 8 bytes

– Even for bigger types, chasing pointers takes time, and allocating memory can be expensive

Unboxed collections: store the actual data, not a pointer!/* array of 1000000 chars */my_array = UArray_new(1000000, sizeof(char));/* set the char at offset 500 to ‘X’ */char *mychar = UArray_at(my_array, 500);*mychar = ‘X’;

35

Page 35: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Boxed and unboxed collections

The collections you’ve seen so far are boxed List_push(mylist, &data); /* list stores a pointer */

Problem: we want an array of 1 million characters– A character is 1 byte

– A pointer to a character is 8 bytes

– Even for bigger types, chasing pointers takes time, and allocating memory can be expensive

Unboxed collections: store the actual data, not a pointer!/* array of 1000000 chars */my_array = UArray_new(1000000, sizeof(char));/* set the char at offset 500 to ‘X’ */char *mychar = UArray_at(my_array, 500);*mychar = ‘X’;

36

Space for 1000000 characters is allocated in the Hanson array…we could use sizeof(struct SomeBigStruct) and that would work too!

Page 36: More on Abstract Data Types Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noah COMP 40: Machine.

© 2010 Noah Mendelsohn

Boxed and unboxed collections

The collections you’ve seen so far are boxed List_push(mylist, &data); /* list stores a pointer */

Problem: we want an array of 1 million characters– A character is 1 byte

– A pointer to a character is 8 bytes

– Even for bigger types, chasing pointers takes time, and allocating memory can be expensive

Unboxed collections: store the actual data, not a pointer!/* array of 1000000 chars */my_array = UArray_new(1000000, sizeof(char));/* set the char at offset 500 to ‘X’ */char *mychar = UArray_at(my_array, 500);*mychar = ‘X’;

37

Uarray_at returns a pointer directly into the data array that’s inside the Hanson implementation…that’s its contract.