Variables and Programs

#drnsecbasicsvarprog#429> In algebra we learn to formulate dependencies between quantities using <#430#>variable expressions<#430#>. A variable is a placeholder that stands for an unknown quantity. For example, a disk of radius r has the approximate area

#displaymath72428#

In this expression, <#432#>r<#432#> stands for any positive number. If we now come across a disk with radius 5, we can determine its area by substituting 5 for r in the above formula and by reducing the resulting expression to a number:

#displaymath72436#

More generally, expressions that contain variables are rules that describe how to compute a number <#433#>when<#433#> we are given values for the variables. external ~<#60347#>Blanks, line breaks, and tabs have no meaning in Scheme. Still, Schemers have adopted rather rigorous rules on program layout, because particular layouts help writers check their parentheses quickly and help readers grasp code quickly. We therefore recommend that you force students to follow the book's conventions of using blank space and indentations. Insist on the format: header, return/enter, expression; a proper amount of white space is automatically inserted by DrScheme after a user hits return/enter. Students should not modify this white space. If it is an unexpected amount of white space, they should check their parentheses. Finally, if all else fails, use <#435#>Scheme|Indent<#435#> or <#436#>Scheme|Indent All<#436#> to adjust white space. The former indents a selected region, the latter the entire <#437#>Definitions<#437#> window.<#60347#> A <#60348#><#438#>PROGRAM<#438#><#60348#> is such a rule. It is a rule that tells us and the computer how to produce data from some other data. Large programs consist of many small programs and combine them in some manner. It is therefore important that programmers name each rule as they write it down. A good name for our sample expression is <#60349#><#439#>area-of-disk<#439#><#60349#>. Using this name, we would express the rule for computing the area of a disk as follows:

<#445#>(d<#445#><#446#>efine<#446#> <#447#>(area-of-disk<#447#> <#448#>r)<#448#> 
  <#449#>(*<#449#> <#450#>3.14<#450#> <#451#>(*<#451#> <#452#>r<#452#> <#453#>r)))<#453#> 
The two lines say that <#60350#><#457#>area-of-disk<#457#><#60350#> is a rule, that it consumes one <#458#>input<#458#>, called <#60351#><#459#>r<#459#><#60351#>, and that the result, or <#460#>output<#460#>, is going to be <#60352#><#461#>(*<#461#>\ <#462#>3.14<#462#>\ <#463#>(*<#463#>\ <#464#>r<#464#>\ <#465#>r))<#465#><#60352#> once we know what number <#60353#><#466#>r<#466#><#60353#> stands for. Programs combine basic operations. In our example, <#60354#><#467#>area-of-disk<#467#><#60354#> uses only one basic operation, multiplication, but <#60355#><#468#>define<#468#><#60355#>d programs may use as many operations as necessary. Once we have defined a program, we may use it as if it were a primitive operation. For each variable listed to the right of the program name, we must supply one input. That is, we may write expressions whose operation is <#60356#><#469#>area-of-disk<#469#><#60356#> followed by a number:
  <#474#>(area-of-disk<#474#> <#475#>5)<#475#>
We also say that we <#60357#><#479#>APPLY<#479#><#60357#> <#60358#><#480#>area-of-disk<#480#><#60358#> to <#60359#><#481#>5<#481#><#60359#>. The application of a <#60360#><#482#>define<#482#><#60360#>d operation is evaluated by copying the expression named <#60361#><#483#>area-of-disk<#483#><#60361#> and by replacing the variable (<#60362#><#484#>r<#484#><#60362#>) with the number we supplied (<#60363#><#485#>5<#485#><#60363#>):
  <#490#>(area-of-disk<#490#> <#491#>5)<#491#> 
<#492#>=<#492#> <#493#>(*<#493#> <#494#>3.14<#494#> <#495#>(*<#495#> <#496#>5<#496#> <#497#>5))<#497#> 
After that, we use plain arithmetic:
  <#505#>...<#505#>
<#506#>=<#506#> <#507#>(*<#507#> <#508#>3.14<#508#> <#509#>25)<#509#> 
<#510#>=<#510#> <#511#>78.5<#511#> 
external ~<#516#>Students may have doubts about this model of how the computer works. These doubts are due to wide-spread misconception about computers. No matter at what level we choose to explain the workings of a computer, we always use an approximation. Initially, it is best to approximate at the most intuitive level---the level of ordinary elementary school arithmetic.<#516#> Many programs consume more than one input. Say we wish to define a program that computes the area of a ring, that is, a disk with a hole in the center: rawhtml5 The area of the ring is that of the outer disk minus the area of the inner disk, which means that the program requires <#517#>two<#517#> unknown quantities: the outer and the inner radii. Let us call these unknown numbers <#60364#><#518#>outer<#518#><#60364#> and <#60365#><#519#>inner<#519#><#60365#>. Then the program that computes the area of a ring is defined as follows:
<#524#>(d<#524#><#525#>efine<#525#> <#526#>(area-of-ring<#526#> <#527#>outer<#527#> <#528#>inner)<#528#> 
  <#529#>(-<#529#> <#530#>(area-of-disk<#530#> <#531#>outer)<#531#> 
     <#532#>(area-of-disk<#532#> <#533#>inner)))<#533#> 
The three lines express that <#60366#><#537#>area-of-ring<#537#><#60366#> is a program, that the program accepts two inputs, called <#60367#><#538#>outer<#538#><#60367#> and <#60368#><#539#>inner<#539#><#60368#>, and that the result is going to be the difference between <#60369#><#540#>(area-of-disk<#540#>\ <#541#>outer)<#541#><#60369#> and <#60370#><#542#>(area-of-disk<#542#><#543#> <#543#><#544#>inner)<#544#><#60370#>. In other words, we have used both basic Scheme operations and <#60371#><#545#>define<#545#><#60371#>d programs in the definition of <#60372#><#546#>area-of-ring<#546#><#60372#>. When we wish to use <#60373#><#547#>area-of-ring<#547#><#60373#>, we must supply two inputs:
  <#552#>(area-of-ring<#552#> <#553#>5<#553#> <#554#>3)<#554#> 
The expression is evaluated in the same manner as <#60374#><#558#>(area-of-disk<#558#><#559#> <#559#><#560#>5)<#560#><#60374#>. We copy the expression from the definition of the program and replace the variable with the numbers we supplied:
  <#565#>(area-of-ring<#565#> <#566#>5<#566#> <#567#>3)<#567#> 
<#568#>=<#568#> <#569#>(-<#569#> <#570#>(area-of-disk<#570#> <#571#>5)<#571#> 
     <#572#>(area-of-disk<#572#> <#573#>3))<#573#> 
<#574#>=<#574#> <#575#>(-<#575#> <#576#>(*<#576#> <#577#>3.14<#577#> <#578#>(*<#578#> <#579#>5<#579#> <#580#>5))<#580#> 
     <#581#>(*<#581#> <#582#>3.14<#582#> <#583#>(*<#583#> <#584#>3<#584#> <#585#>3)))<#585#> 
<#586#>=<#586#> <#587#>...<#587#> 
The rest is plain arithmetic.
external ~<#60375#>Explain that these exercises demonstrate that programs require a fair amount of <#594#>domain knowledge<#594#>. Here the relevant domains are physics, chemistry, business, geometry, and algebra. In general, it can be anything: science, engineering, music, marketing, literature The first exercise is critical. It illustrates that one function can be used with three different user-interfaces. If students don't believe their functions play a role, have them add a mistake to the function and watch how things change. The only way to achieve this compatibility of functions with many different interfaces is to develop the functions independently of <#595#>all<#595#> input and output considerations. In software engineering terminology, this separation of concerns is called the <#596#>model-view<#596#> pattern. We will study the model-view pattern and how to create our own GUI views in more detail in part~#partabstract#597>. Without some background in writing plain functions, beginners cannot appreciate the idea. Use the Help Desk to read the documentation for the teachpack and how to install teachpacks. The documentation provides a bit more information. For now, the quotes around the file names are just funny things. Later on we will find out that this is just another kind of data. Similarly, handing a function to another function may appear strange. It is after all an advanced mathematical topic. But in good programming, especially GUI programming, this happens all the time. Again, we will study the idea in part~#partabstract#598>. <#60375#> <#599#>Exercise 2.2.1<#599#> Define the program <#72144#><#70643#><#601#>Fahrenheit<#601#><#60376#><#602#><#602#><#603#>-;SPMgt;<#603#><#604#><#604#><#60376#><#605#>Celsius<#605#><#70643#><#72144#>, which consumes a temperature measured in Fahrenheit and produces the Celsius equivalent. Use a chemistry or physics book to look up the conversion formula. When the function is fully developed, test it using the teachpack <#608#>convert.ss<#608#>. The teachpack provides three functions: <#60378#><#609#>convert-gui<#609#><#60378#>, <#60379#><#610#>convert-repl<#610#><#60379#>, and <#60380#><#611#>convert-file<#611#><#60380#>. The first creates a graphical user interface. Use it with
<#616#>(convert-gui<#616#> <#70644#><#617#>Fahrenheit<#617#><#60381#><#618#><#618#><#619#>-;SPMgt;<#619#><#620#><#620#><#60381#><#621#>Celsius<#621#><#70644#><#622#>)<#622#>
The expression will spawn a new window in which users can manipulate sliders and buttons. The second emulates the <#626#>Interactions<#626#> window. Users are asked to enter a Fahrenheit temperature, which the program reads, evaluates, and prints. Use it via
<#631#>(convert-repl<#631#> <#70645#><#632#>Fahrenheit<#632#><#60382#><#633#><#633#><#634#>-;SPMgt;<#634#><#635#><#635#><#60382#><#636#>Celsius<#636#><#70645#><#637#>)<#637#>
The last operation processes entire files. To use it, create a file with those numbers that are to be converted. Separate the numbers with blank spaces or newlines. The function reads the entire file, converts the numbers, and writes the results into a new file. Here is the expression:
<#645#>(convert-file<#645#> <#646#>``in.dat''<#646#> <#70646#><#647#>Fahrenheit<#647#><#60383#><#648#><#648#><#649#>-;SPMgt;<#649#><#650#><#650#><#60383#><#651#>Celsius<#651#><#70646#> <#652#>``out.dat'')<#652#>
This assumes that the name of the newly created file is <#656#>in.dat<#656#> and that we wish the results to be written to the file <#657#>out.dat<#657#>. For more information, use DrScheme's Help Desk to look up the teachpack <#658#>convert.ss<#658#>.~ external Solution<#60384#><#60384#> <#664#>Exercise 2.2.2<#664#> Define the program <#72145#><#70647#><#666#>dollar<#666#><#60385#><#667#><#667#><#668#>-;SPMgt;<#668#><#669#><#669#><#60385#><#670#>euro<#670#><#70647#><#72145#>, which consumes a number of dollars and produces the euro equivalent. Use the currency table in the newspaper to look up the current exchange rate. external Solution<#60386#><#60386#> <#676#>Exercise 2.2.3<#676#> Define the program <#60387#><#678#>triangle<#678#><#60387#>. It consumes the length of a triangle's side and its height. The program produces the area of the triangle. Use a geometry book to look up the formula for computing the area of a triangle. external Solution<#60388#><#60388#> <#684#>Exercise 2.2.4<#684#> Define the program <#60389#><#686#>convert3<#686#><#60389#>. It consumes three digits, starting with the least significant digit, followed by the next most significant one and so on. The program produces the corresponding number. For example:
<#691#>(convert3<#691#> <#692#>1<#692#> <#693#>2<#693#> <#694#>3)<#694#> <#695#>=<#695#> <#696#>321<#696#>
Use an algebra book to find out how such a conversion works.~ external Solution<#60390#><#60390#> <#705#>Exercise 2.2.5<#705#> A typical exercise in an algebra book asks the reader to evaluate an expression like

#displaymath72438#

for n = 2, n = 5, and n = 9. Using Scheme, we can formulate such an expression as a program and use the program as many times as necessary. Here is the program that corresponds to the above expression:

<#714#>(d<#714#><#715#>efine<#715#> <#716#>(f<#716#> <#717#>n)<#717#>
  <#718#>(+<#718#> <#719#>(/<#719#> <#720#>n<#720#> <#721#>3)<#721#> <#722#>2))<#722#> 
First determine the result of the expression at n = 2, n = 5, and n = 9 by hand, then with DrScheme's stepper. Also formulate the following three expressions as programs:
  1. #tex2html_wrap_inline72452#
  2. #tex2html_wrap_inline72454#
  3. #tex2html_wrap_inline72456#
Determine their results for n = 2 and n = 9 by hand and with DrScheme.~ external Solution<#60391#><#60391#>