Vancouver Institute Lectures

Programming: Poetry, gears or magic? Kiczales, Gregor 2001-02-17

Your browser doesn't seem to have a PDF viewer, please download the PDF to view this item.

Notice for Google Chrome users:
If you are having trouble viewing or searching the PDF with Google Chrome, please download it here instead.

Item Metadata

Download

Media
12708-at_2513_Kiczales.mp3 [ 76.03MB ]
12708-kiczales-vinst-2-17-01.pdf [ 1.65MB ]
Metadata
JSON: 12708-1.0102688.json
JSON-LD: 12708-1.0102688-ld.json
RDF/XML (Pretty): 12708-1.0102688-rdf.xml
RDF/JSON: 12708-1.0102688-rdf.json
Turtle: 12708-1.0102688-turtle.txt
N-Triples: 12708-1.0102688-rdf-ntriples.txt
Original Record: 12708-1.0102688-source.json
Full Text
12708-1.0102688-fulltext.txt
Citation
12708-1.0102688.ris

Full Text

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 (<test>) 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: <promise> click:   <promise> 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

Cite

Citation Scheme:

        

Citations by CSL (citeproc-js)

Usage Statistics

Share

Embed

Customize your widget with the following options, then copy and paste the code below into the HTML of your page to embed this item in your website.
                        
                            <div id="ubcOpenCollectionsWidgetDisplay">
                            <script id="ubcOpenCollectionsWidget"
                            src="{[{embed.src}]}"
                            data-item="{[{embed.item}]}"
                            data-collection="{[{embed.collection}]}"
                            data-metadata="{[{embed.showMetadata}]}"
                            data-width="{[{embed.width}]}"
                            data-media="{[{embed.selectedMedia}]}"
                            async >
                            </script>
                            </div>
                        
                    
IIIF logo Our image viewer uses the IIIF 2.0 standard. To load this item in other compatible viewers, use this url:
https://iiif.library.ubc.ca/presentation/dsp.12708.1-0102688/manifest

Comment

Related Items