Vancouver Institute Lectures

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

You don't seem to have a PDF reader installed, try download the pdf

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 groupProgramming: Poetry, Gears or Magic?Gregor KiczalesNSERC, Xerox, Sierra Systems Software Design ChairProfessor of Computer ScienceUniversity of British Columbia2/17/01 Vancouver Institute 2 UBC software modularity groupsubject of the talkprogramming 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 substantive2/17/01 Vancouver Institute 3 UBC software modularity groupthemes 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 weask?• what might happen in the future?• how can a program be beautiful or elegant• technical and esthetic principles of the field2/17/01 Vancouver Institute 4 UBC software modularity groupcurrent applications2/17/01 Vancouver Institute 5 UBC software modularity groupcurrent applications2/17/01 Vancouver Institute 6 UBC software modularity groupcurrent applications2/17/01 Vancouver Institute 7 UBC software modularity groupa ‘simple’ browser application2/17/01 Vancouver Institute 8 UBC software modularity groupa ‘simple’ browser application2/17/01 Vancouver Institute 9 UBC software modularity groupa very simple applicationprint numbers from 1 to 31232/17/01 Vancouver Institute 10 UBC software modularity groupdifferent scales10 lines104 lines106 lines1232/17/01 Vancouver Institute 11 UBC software modularity groupPart I – starting smalldoing something 3 times123before we can do thiswe surely need to beable to do this… write a program to print 1 2 3using ~1964 technology2/17/01 Vancouver Institute 12 UBC software modularity groupwho’s on first?• ‘goto’ jumps to that label• goto B, goto C, goto A• what are A, B, C?• what do they do?      i = 1A:    if i < 4        then goto B        else goto CB:    print(i)      i = i + 1      goto AC:2/17/01 Vancouver Institute 13 UBC software modularity groupover, 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 = 1TEST: if i < 4        then goto BODY        else goto ENDBODY: print(i)      i = i + 1      goto TESTEND:2/17/01 Vancouver Institute 14 UBC software modularity groupelegant coding style      i = 1LOOP: 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– idiomatic2/17/01 Vancouver Institute 15 UBC software modularity groupPL support• eliminate goto• add explicit while loop– test and time of test– body { … }i = 1while (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 costbusinesses "hundreds of millions of dollars"• generated more response by far than any other issue everconsidered in pages of the CACM•  many principles of the field forged during this time2/17/01 Vancouver Institute 17 UBC software modularity groupother optionsi = 1while (i < 4) {  print(i)  i = i + 1}i = 1while (i != 4) {  print(i)  i = i + 1}some argue that writing“i not equal to 4”more clearly expresses whenthe loop endsyou can still get a good fightover which of these is best2/17/01 Vancouver Institute 18 UBC software modularity groupother optionsdotimes (i 3) {  print(i)}most clearmany argue too special-purposeyou can still get a good fightover which of these is besti = 1do {  print(i)  i = i + 1} until (i = 3)test at endmakes end condition more cleardo (i = 1, i < 4, i++) {  print(i)}general-purposebut still clearly a loop2/17/01 Vancouver Institute 19 UBC software modularity groupwhy 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 pointsprograms must bewell-written2/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 102/17/01 Vancouver Institute 21 UBC software modularity groupPart II – a simple application• an image browser– 3 choice menu– display image… implement this simple image browserusing structured programming2/17/01 Vancouver Institute 22 UBC software modularity groupsimplified 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 groupsimplified 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 groupsimplified 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 groupsimplified 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 groupsimplified 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 groupsimplified 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 groupsimplified 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 groupsimplified 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 groupsimplified 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 groupsimplified 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 groupsimplified 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 groupseparation 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 groupseparation 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 groupprinciples for separation• group by:– “shared secrets”– common functionality– no upcalls• modules with– crisp, narrow interfacesgraphics:  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 groupPL 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 modulemodule abstractionmechanismsmodule menus {  exports:    radio_menu(labels)    button_menu(labels)    check_buttons(menu)}2/17/01 Vancouver Institute 37 UBC software modularity groupthinking architecturally• abstraction lets us– look at overall system structuremenusgraphicshaida_browser2/17/01 Vancouver Institute 38 UBC software modularity groupthinking architecturally• abstraction lets us– look at overall system structure– zoom in on one part of the system at a timemenus:  radio_menu(labels)  button_menu(labels)  check_buttons(menu)haida_browsergraphics2/17/01 Vancouver Institute 39 UBC software modularity groupthinking architecturally• abstraction lets us– look at overall system structure– zoom in on one part of the system at a time• more or less detailhaida_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);    }  }menusgraphics2/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 linesmenusgraphicshaida_browser2/17/01 Vancouver Institute 41 UBC software modularity groupPart III – systems of applications• Powerpoint, Outlook, browsers…• tangling problems arise again2/17/01 Vancouver Institute 42 UBC software modularity groupvariations of functionalitycombo: text box and listtoolbarstoolbar buttons                even with modular programmingthis appears to be incredibly complex…pull-down menuscolor choosers2/17/01 Vancouver Institute 43 UBC software modularity groupcoping 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 world2/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 classes2/17/01 Vancouver Institute 45 UBC software modularity groupa class hierarchyToggleButtonMenuMenuCheckBoxMenu RadioButtonMenuButtonMenu2/17/01 Vancouver Institute 46 UBC software modularity groupoperations on objectsdisplay: boxes, labelsclick:   highlightdisplay: boxes,         maybe checks,         labelsclick:   set/cleardisplay: circle,         maybe dots,         labelsclick:   set/clear         AND clear othersToggleButtonMenuCheckBoxMenu RadioButtonMenuMenuButtonMenu2/17/01 Vancouver Institute 47 UBC software modularity groupinheritancedisplay: boxes, labelsclick:   highlightdisplay: boxes,         maybe checks,         labelsclick:   set/cleardisplay: circle,         maybe dots,         labelsclick:   set/clear         AND clear othersToggleButtonMenuCheckBoxMenu RadioButtonMenuMenuButtonMenudisplay: <promise>click:   <promise>click:   set/clearclasses are“cookie cutters” for objects2/17/01 Vancouver Institute 48 UBC software modularity groupPL supportclass 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” ofToggleButtondefines two operationsthis operation buildson the superclass’sversion of it2/17/01 Vancouver Institute 49 UBC software modularity groupOOP is useful2/17/01 Vancouver Institute 50 UBC software modularity groupOOP is elegant2/17/01 Vancouver Institute 51 UBC software modularity groupOOP 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 grouptangling  structurei = 1while (i < 5) {  print(i)  i = i + 1}structuredcontrolconstructs      i = 1TEST: if i < 5        then goto BODY        else goto ENDBODY: print(i)      i = i + 1      goto TESTEND:AbstractButtonButton ToggleButtonRadioButtonCheckBoxclassification &specializationof objectsmenusgraphicssimple_browsermodules withnarrowinterfaces  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++;    }  }crosscuttingaspects?2/17/01 Vancouver Institute 54 UBC software modularity groupPart IV – an analogydesigning and building a simple bridge...2/17/01 Vancouver Institute 55 UBC software modularity groupcrosscutting modelssimplestaticsmoredetailedstaticssimpledynamicsm2/17/01 Vancouver Institute 56 UBC software modularity groupmodels vs. artifactsabstract modeli = 1while (i < 4) {  print(i)  i = i + 1}real artifactprograms are boththis is magic2/17/01 Vancouver Institute 57 UBC software modularity groupcrosscutting programs?mmodule 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 groupvm_faultvm_pager_getpagesvnode_pager_getpagesffs_getpagesffs_validufs_bmapffs_calc_size……VM module“aspect-oriented programming”• more than onemodularity is possible– order of execution– context of use– inter-object collaborationFFS module if (((fs.object->type != OBJT_DEFAULT) &&                                (((fault_flags & VM_FAULT_WIRE_MASK) == 0) || wired))                    || (fs.object == fs.first_object)) {                        if (fs.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 (fs.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 (fs.first_object->behavior == OBJ_RANDOM) {                                ahead = 0;                                behind = 0;                        } else {                                behind = (vaddr - 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 ||                                                (mt->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(mt);                                        } else {                                                vm_page_cache(mt);                                        }                                }                                ahead += behind;                                behind = 0;                        }if (fs.first_object->behavior == OBJ_RANDOM) {                                ahead = 0;                                behind = 0;                        } else {                                behind = (vaddr - 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 grouptangling  structurei = 1while (i < 5) {  print(i)  i = i + 1}structuredcontrolconstructs      i = 1TEST: if i < 5        then goto BODY        else goto ENDBODY: print(i)      i = i + 1      goto TESTEND:AbstractButtonButton ToggleButtonRadioButtonCheckBoxclassification &specializationof objectsmenusgraphicssimple_browsermodules withnarrowinterfaces  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++;    }  }crosscuttingaspects

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}]}"
                            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:
http://iiif.library.ubc.ca/presentation/dsp.12708.1-0102688/manifest

Comment

Related Items