@prefix vivo: . @prefix edm: . @prefix ns0: . @prefix dcterms: . @prefix dc: . @prefix skos: . vivo:departmentOrSchool "Science, Faculty of"@en, "Computer Science, Department of"@en ; edm:dataProvider "DSpace"@en ; ns0:rightsCopyright "Kiczales, Gregor"@en ; dcterms:creator "Kiczales, Gregor"@en ; dcterms:issued "2016-11-24T12:40:56"@en, "2001-02-17"@en ; dcterms:description "Item consists of a digitized copy of an audio recording of a Vancouver Institute lecture given by Gregor Kiczales on February 17, 2001. Original audio recording available in the University Archives (UBC AT 2513). Also included is a PDF copy of lecture slides."@en ; edm:aggregatedCHO "https://circle.library.ubc.ca/rest/handle/2429/13153?expand=metadata"@en ; dcterms:extent "79723624 bytes"@en, "1735070 bytes"@en ; dc:format "audio/mp3"@en, "application/pdf"@en ; skos:note "software modularity group Programming: Poetry, Gears or Magic? Gregor Kiczales NSERC, Xerox, Sierra Systems Software Design Chair Professor of Computer Science University of British Columbia 2/17/01 Vancouver Institute 2 UBC software modularity group subject of the talk programming and programming languages (PL) • use demands of current software systems • to look at 4 generations of PL research – problems addressed – core idea – what we learned about building programs • look at some (fairly) real code – don’t worry! you will be able to read this code – idealized but substantive 2/17/01 Vancouver Institute 3 UBC software modularity group themes to explore • what is code? what are “lines of code”? • why is programming so interesting? so hard? • why is software so fragile? • what is the nature of the research? what questions do we ask? • what might happen in the future? • how can a program be beautiful or elegant • technical and esthetic principles of the field 2/17/01 Vancouver Institute 4 UBC software modularity group current applications 2/17/01 Vancouver Institute 5 UBC software modularity group current applications 2/17/01 Vancouver Institute 6 UBC software modularity group current applications 2/17/01 Vancouver Institute 7 UBC software modularity group a ‘simple’ browser application 2/17/01 Vancouver Institute 8 UBC software modularity group a ‘simple’ browser application 2/17/01 Vancouver Institute 9 UBC software modularity group a very simple application print numbers from 1 to 3 1 2 3 2/17/01 Vancouver Institute 10 UBC software modularity group different scales 10 lines 10 4 lines 10 6 lines 1 2 3 2/17/01 Vancouver Institute 11 UBC software modularity group Part I – starting small doing something 3 times 1 2 3 before we can do this we surely need to be able to do this … write a program to print 1 2 3 using ~1964 technology 2/17/01 Vancouver Institute 12 UBC software modularity group who’s on first? • ‘goto’ jumps to that label • goto B, goto C, goto A • what are A, B, C? • what do they do? i = 1 A: if i < 4 then goto B else goto C B: print(i) i = i + 1 goto A C: 2/17/01 Vancouver Institute 13 UBC software modularity group over, back, and all around • test, body and end • but… – what happens when? – first i is 1 – how can it not be < 4 ? – what is this braid doing? i = 1 TEST: if i < 4 then goto BODY else goto END BODY: print(i) i = i + 1 goto TEST END: 2/17/01 Vancouver Institute 14 UBC software modularity group elegant coding style i = 1 LOOP: print(i) i = i + 1 if i < 4 then goto LOOP • really one simple loop – no “crossing gotos” – clear tag names • this is “elegant” code – concise – nicely named – reflects the structure – idiomatic 2/17/01 Vancouver Institute 15 UBC software modularity group PL support • eliminate goto • add explicit while loop – test and time of test – body { … } i = 1 while (i < 4) { print(i) i = i + 1 } • PL designer makes the rules – new words, new grammar • you will write elegant code – don’t use words like “goto” – say while when you “mean it” (actually, we can only encourage good style) 2/17/01 Vancouver Institute 16 UBC software modularity group “structured programming” • a ‘spirited’ debate - Dijkstra, E. “GOTO Statement Considered Harmful” 1968 - Wulf, W. A. “A Case Against the GOTO” 1972 - Knuth, D. “Structured Programming with goto Statements” 1974 - Rubin, F. “ ‘GOTO Considered Harmful’ Considered Harmful” 1987 • letter to editor of CACM asserts goto-less programming has cost businesses \"hundreds of millions of dollars\" • generated more response by far than any other issue ever considered in pages of the CACM • many principles of the field forged during this time 2/17/01 Vancouver Institute 17 UBC software modularity group other options i = 1 while (i < 4) { print(i) i = i + 1 } i = 1 while (i != 4) { print(i) i = i + 1 } some argue that writing “i not equal to 4” more clearly expresses when the loop ends you can still get a good fight over which of these is best 2/17/01 Vancouver Institute 18 UBC software modularity group other options dotimes (i 3) { print(i) } most clear many argue too special-purpose you can still get a good fight over which of these is best i = 1 do { print(i) i = i + 1 } until (i = 3) test at end makes end condition more clear do (i = 1, i < 4, i++) { print(i) } general-purpose but still clearly a loop 2/17/01 Vancouver Institute 19 UBC software modularity group why does this matter? • to the computer? – it doesn’t, issues like this don’t confuse the computer! • but, ~10x maintenance vs. original development • programs always change – debug – add new functionality – integrate with new systems • programs must be readable by others – have to tell a story – have a coherent structure – focus on the key points programs must be well-written 2/17/01 Vancouver Institute 20 UBC software modularity group “structured programming” • peak of research ~ 64 – 75 • structured control mechanisms – eliminate ‘goto’ – add explicit loops: do, while – add explicit tests: if () then { … } else { … }, case… –  prohibit non-standard control structures –  ‘encourages good style, use of idioms’ • code is easier to understand –  easier to write, easier to read, easier to debug • abstraction: a ‘while loop’ vs. details of looping –  100 lines of code felt like 10 2/17/01 Vancouver Institute 21 UBC software modularity group Part II – a simple application • an image browser – 3 choice menu – display image … implement this simple image browser using structured programming 2/17/01 Vancouver Institute 22 UBC software modularity group simplified implementation main () { draw_label(“Haida Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } 2/17/01 Vancouver Institute 23 UBC software modularity group simplified implementation main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } 2/17/01 Vancouver Institute 24 UBC software modularity group simplified implementation main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } 2/17/01 Vancouver Institute 25 UBC software modularity group simplified implementation main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } radio_button (n) { draw_circle(get_x(), get_y(), 3); } 2/17/01 Vancouver Institute 26 UBC software modularity group simplified implementation main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } 2/17/01 Vancouver Institute 27 UBC software modularity group simplified implementation main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } 2/17/01 Vancouver Institute 28 UBC software modularity group simplified implementation main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } button_menu(labels) { i = 0; while (i < labels.size) { draw_label(labels[i]); set_y(get_y() + BUTTON_H); i++; } } 2/17/01 Vancouver Institute 29 UBC software modularity group simplified implementation main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } button_menu(labels) { i = 0; while (i < labels.size) { draw_label(labels[i]); set_y(get_y() + BUTTON_H); i++; } } 2/17/01 Vancouver Institute 30 UBC software modularity group simplified implementation main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } button_menu(labels) { i = 0; while (i < labels.size) { draw_label(labels[i]); set_y(get_y() + BUTTON_H); i++; } } 2/17/01 Vancouver Institute 31 UBC software modularity group simplified implementation main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } draw_image (img) { w = img.width; h = img.height; do (r = 0; r < h; r++) do (c = 0; c < w; c++) WINDOW[r][c] = img[r][c]; } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } button_menu(labels) { i = 0; while (i < labels.size) { draw_label(labels[i]); set_y(get_y() + BUTTON_H); i++; } } ha! 2/17/01 Vancouver Institute 32 UBC software modularity group simplified implementation main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } draw_image (img) { w = img.width; h = img.height; do (r = 0; r < h; r++) do (c = 0; c < w; c++) WINDOW[r][c] = img[r][c]; } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } button_menu(labels) { i = 0; while (i < labels.size) { draw_label(labels[i]); set_y(get_y() + BUTTON_H); i++; } } ha! 2/17/01 Vancouver Institute 33 UBC software modularity group separation of concerns main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } draw_image (img) { w = img.width; h = img.height; do (r = 0; r < h; r++) do (c = 0; c < w; c++) WINDOW[r][c] = img[r][c]; } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } button_menu(labels) { i = 0; while (i < labels.size) { draw_label(labels[i]); set_y(get_y() + BUTTON_H); i++; } } 2/17/01 Vancouver Institute 34 UBC software modularity group separation of concerns main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } draw_image (img) { w = img.width; h = img.height; do (r = 0; r < h; r++) do (c = 0; c < w; c++) WINDOW[r][c] = img[r][c]; } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } button_menu(labels) { i = 0; while (i < labels.size) { draw_label(labels[i]); set_y(get_y() + BUTTON_H); i++; } } 2/17/01 Vancouver Institute 35 UBC software modularity group principles for separation • group by: – “shared secrets” – common functionality – no upcalls • modules with – crisp, narrow interfaces graphics: draw_image(img) draw_label(string) draw_circle(x, y, r) haida_browser: main () { draw_label(“Haida Art Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } menus: radio_menu(labels) button_menu(labels) check_buttons(menu) 2/17/01 Vancouver Institute 36 UBC software modularity group PL support • clear module interfaces – explicit – enforced • only through front door • can’t ‘read the mail’ – type systems – opacity • ‘abstraction’ mechanisms – from outside can only see abstraction of module module abstraction mechanisms module menus { exports: radio_menu(labels) button_menu(labels) check_buttons(menu) } 2/17/01 Vancouver Institute 37 UBC software modularity group thinking architecturally • abstraction lets us – look at overall system structure menus graphics haida_browser 2/17/01 Vancouver Institute 38 UBC software modularity group thinking architecturally • abstraction lets us – look at overall system structure – zoom in on one part of the system at a time menus: radio_menu(labels) button_menu(labels) check_buttons(menu)haida_browser graphics 2/17/01 Vancouver Institute 39 UBC software modularity group thinking architecturally • abstraction lets us – look at overall system structure – zoom in on one part of the system at a time • more or less detail haida_browser: main () { draw_label(“Haida Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } menus graphics 2/17/01 Vancouver Institute 40 UBC software modularity group “modular programming” • separation of concerns – organize code according to common functionality – PL mechanisms • enforce secrecy of module internals • abstraction – enables architectural thinking – treat the module as its interface – 100 modules can feel like 1000 lines menus graphics haida_browser 2/17/01 Vancouver Institute 41 UBC software modularity group Part III – systems of applications • Powerpoint, Outlook, browsers… • tangling problems arise again 2/17/01 Vancouver Institute 42 UBC software modularity group variations of functionality combo: text box and list toolbars toolbar buttons even with modular programming this appears to be incredibly complex… pull-down menus color choosers 2/17/01 Vancouver Institute 43 UBC software modularity group coping with complexity • Simula [Dahl & Nygaard 64, 68] • Smalltalk [Alan Kay 70 – 80] • we cope with complexity all the time – world has a diversity of complex objects – abstraction, classification and specialization • “model” programs after the world 2/17/01 Vancouver Institute 44 UBC software modularity group “object-oriented programming” • aka OOP • “objects” are… – animate • know how to do things • code plus data • little computers waiting to be told what to do – classified • specializations of other objects • a “class” is a cookie cutter for objects – specializations of other classes 2/17/01 Vancouver Institute 45 UBC software modularity group a class hierarchy ToggleButtonMenu Menu CheckBoxMenu RadioButtonMenu ButtonMenu 2/17/01 Vancouver Institute 46 UBC software modularity group operations on objects display: boxes, labels click: highlight display: boxes, maybe checks, labels click: set/clear display: circle, maybe dots, labels click: set/clear AND clear others ToggleButtonMenu CheckBoxMenu RadioButtonMenu Menu ButtonMenu 2/17/01 Vancouver Institute 47 UBC software modularity group inheritance display: boxes, labels click: highlight display: boxes, maybe checks, labels click: set/clear display: circle, maybe dots, labels click: set/clear AND clear others ToggleButtonMenu CheckBoxMenu RadioButtonMenu Menu ButtonMenu display: click: click: set/clear classes are “cookie cutters” for objects 2/17/01 Vancouver Institute 48 UBC software modularity group PL support class RadioButtonMenu extends ToggleButtonMenu { void display() { i = 0; while (i < buttons.length) { drawCircle(); drawLabel(buttons[i]); if ( buttons[i].isSet() ) drawHighlight(i); } } void click(i) { super(i); clearOthers(i); } } a “subclass” of ToggleButton defines two operations this operation builds on the superclass’s version of it 2/17/01 Vancouver Institute 49 UBC software modularity group OOP is useful 2/17/01 Vancouver Institute 50 UBC software modularity group OOP is elegant 2/17/01 Vancouver Institute 51 UBC software modularity group OOP is powerful… 2/17/01 Vancouver Institute 52 UBC software modularity group “object-oriented programming” • objects are – code plus data – little computers – arranged in class hierarchies • abstraction, classification & specialization – think in terms of class hierarchy – OOP  OOD – write code by drawing pictures • draw class diagrams • produce class code – only write things once! 2/17/01 Vancouver Institute 53 UBC software modularity group tangling  structure i = 1 while (i < 5) { print(i) i = i + 1 } structured control constructs i = 1 TEST: if i < 5 then goto BODY else goto END BODY: print(i) i = i + 1 goto TEST END: AbstractButton Button ToggleButton RadioButtonCheckBox classification & specialization of objects menus graphics simple_browser modules with narrow interfaces main () { draw_label(“Haida Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } draw_image (img) { w = img.width; h = img.height; do (r = 0; r < h; r++) do (c = 0; c < w; c++) WINDOW[r][c] = img[r][c]; } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } button_menu(labels) { i = 0; while (i < labels.size) { draw_label(labels[i]); set_y(get_y() + BUTTON_H); i++; } } crosscutting aspects? 2/17/01 Vancouver Institute 54 UBC software modularity group Part IV – an analogy designing and building a simple bridge... 2/17/01 Vancouver Institute 55 UBC software modularity group crosscutting models simple statics more detailed statics simple dynamics m 2/17/01 Vancouver Institute 56 UBC software modularity group models vs. artifacts abstract model i = 1 while (i < 4) { print(i) i = i + 1 } real artifact programs are both this is magic 2/17/01 Vancouver Institute 57 UBC software modularity group crosscutting programs? m module menus { exports: radio_menu(labels) button_menu(labels) check_buttons(menu) } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } radio_button (n) { draw_circle(get_x(), get_y(), 3); } button_menu(labels) { i = 0; while (i < labels.size) { draw_label(labels[i]); set_y(get_y() + BUTTON_H); i++; } } ? 2/17/01 Vancouver Institute 58 UBC software modularity group vm_fault vm_pager_getpages vnode_pager_getpages ffs_getpages ffs_valid ufs_bmap ffs_calc_size … …VM module “aspect-oriented programming” • more than one modularity is possible – order of execution – context of use – inter-object collaboration FFS module if (((fs.object->type != OBJT_DEFAULT) && (((fault_flags & VM_FAULT_WIRE_MASK) == 0) || wired)) || (fs.object == fs. first_object)) { if (f s.pindex >= fs.object->size) { unlock_and_deallocate(&fs) ; return (KERN_PROTECTION_FAILURE); } /* * Allocate a new page for this object/offset pair. */ fs.m = vm_page_alloc( fs.object, fs.pindex, (fs. vp || fs.object->backing_object)? VM_ALLOC_NORMAL: VM_ALLOC_ZERO); if (f s. m == NULL) { unlock_and_deallocate(&fs) ; VM_WAIT; goto RetryFault; } } (((fault_flags & VM_FAULT_WIRE_MASK) == 0) || wired)) { int rv; int reqpage; int ahead, behind; if (f s. first_object->behavior == OBJ_RANDOM) { ahead = 0; behind = 0; } else { behind = (v addr - fs.entry->start) >> PAGE_SHIFT; if (behind > VM_FAULT_READ_BEHIND) behind = VM_FAULT_READ_BEHIND; : aspect normal_prefetching { pointcut vm_fault_cflow( vm_map_t map ): cflow( calls( int vm_fault( map, .. ))); pointcut ffs_getpages_cflow( vm_object_t obj, vm_page_t* plist, int len, int fpage ): cflow( calls( int ffs_getpages( obj, plist, len, fpage ))); before( vm_map_t map, vm_object_t obj, vm_page_t* plist, int len, int fpage ): calls( int vnode_pager_getpages( obj, plist, len, fpage )) && vm_fault_cflow( map ) { if ( obj->declared_behaviour == NORMAL ) { vm_map_lock( map ); plan_and_alloc_normal( obj, plist, len, fpage ); vm_map_unlock( map ); } } after( vm_object_t obj, vm_page_t* plist, int len, int fpage, int valid ): calls( valid ffs_valid(..) ) && ffs_getpages_cflow( obj, plist, len, fpage ) { if ( valid ) dealloc_all_prefetch_pages( obj, plist, len, fpage ); } after( vm_object_t obj, vm_page_t* plist, int len, int fpage, int error, int reqblkno ): calls( error ufs_bmap( struct vnode*, reqblkno, ..) ) && ffs_getpages_cflow( obj, plist, len, fpage ) { if ( error || (reqblkno == -1) ) dealloc_all_prefetch_pages( obj, plist, len, fpage ); aspect sequential_prefetching { pointcut vm_fault_cflow( vm_map_t map ): cflow( calls( int vm_fault( map, .. ))); pointcut ffs_read_cflow( struct vnode* vp, struct uio* io_inf, int size, struct buff** bpp ): cflow( calls( int ffs_read( vp, io_inf, size, bpp ))); before( vm_map_t map, vm_object_t obj, vm_page_t* plist, int len, int fpage ): calls( int vnode_pager_getpages( obj, plist, len, fpage )) && vm_fault_cflow( map ) { if ( obj->declared_behaviour == SEQUENTIAL ) { vm_map_lock( map ); plan_and_alloc_sequential( obj, plist, len, fpage ); vm_map_unlock( map ); } } around( vm_object_t obj, vm_page_t* plist, int len, int fpage ): calls( int ffs_getpages( obj, plist, len, fpage )) { if ( obj->behaviour == SEQUENTIAL ) { struct vnode* vp = obj->handle; struct uio* io_inf = io_prep( plist[fpage]->pindex, MAXBSIZE, curproc ); int error = ffs_read( vp, io_inf, MAXBSIZE, curproc->p_ucred ); return cleanup_after_read( error, obj, plist, len, fpage ); } else proceed; } after( struct uio* io_info, int size, struct buf** bpp ): else firstpindex = fs.first_pindex - 2*(VM_FAULT_READ_BEHIND + VM_FAULT_READ_AHEAD + 1); for(tmppindex = fs.first_pindex - 1; tmppindex >= firstpindex; --tmppindex) { vm_page_t mt; mt = vm_page_lookup( fs.first_object, tmppindex) ; if (mt == NULL || (mt->valid != VM_PAGE_BITS_ALL)) break; if (mt- >busy || (m t->flags & (PG_BUSY | PG_FICTITIOUS)) || mt->hold_count || mt->wire_count) continue; if (mt- >dirty == 0) vm_page_test_dirty(mt) ; if (mt- >dirty) { vm_page_protect(mt, VM_PROT_NONE); vm_page_deactivate(m t); } else { vm_page_cache(m t); } } ahead += behind; behind = 0; } if (f s. first_object->behavior == OBJ_RANDOM) { ahead = 0; behind = 0; } else { behind = (v addr - fs.entry->start) >> PAGE_SHIFT; if (behind > VM_FAULT_READ_BEHIND) behind = VM_FAULT_READ_BEHIND; ahead = ((fs.entry->end - vaddr) >> PAGE_SHIFT) - 1; if (ahead > VM_FAULT_READ_AHEAD) ahead = VM_FAULT_READ_AHEAD; : 2/17/01 Vancouver Institute 59 UBC software modularity group tangling  structure i = 1 while (i < 5) { print(i) i = i + 1 } structured control constructs i = 1 TEST: if i < 5 then goto BODY else goto END BODY: print(i) i = i + 1 goto TEST END: AbstractButton Button ToggleButton RadioButtonCheckBox classification & specialization of objects menus graphics simple_browser modules with narrow interfaces main () { draw_label(“Haida Browser”); m = radio_menu( {“Whale”, “Eagle”, “Dogfish”}); q = button_menu({“Quit”}); while ( ! check_buttons(q) ) { n = check_buttons(m); draw_image(n); } } draw_label (string) { w = calculate_width(string); print(string, WINDOW_PORT); set_x(get_x() + w); } draw_image (img) { w = img.width; h = img.height; do (r = 0; r < h; r++) do (c = 0; c < w; c++) WINDOW[r][c] = img[r][c]; } radio_menu(labels) { i = 0; while (i < labels.size) { radio_button(i); draw_label(labels[i]); set_y(get_y() + RADIO_BUTTON_H); i++; } } draw_circle (x, y, r) { %%primitive_oval(x, y, 1, r); } radio_button (n) { draw_circle(get_x(), get_y(), 3); } button_menu(labels) { i = 0; while (i < labels.size) { draw_label(labels[i]); set_y(get_y() + BUTTON_H); i++; } } crosscutting aspects"@en ; edm:isShownAt "10.14288/1.0102688"@en ; dcterms:language "eng"@en ; ns0:peerReviewStatus "Unreviewed"@en ; edm:provider "Vancouver : University of British Columbia Library"@en ; dcterms:rights "Attribution-NonCommercial-NoDerivatives 4.0 International"@en ; ns0:rightsURI "http://creativecommons.org/licenses/by-nc-nd/4.0/"@en ; ns0:scholarLevel "Other"@en ; dcterms:title "Programming: Poetry, gears or magic?"@en ; dcterms:type "Sound"@en ; ns0:identifierURI "http://hdl.handle.net/2429/13153"@en .