Section 2

Numbers, Expressions, Simple Programs

2.1  Numbers and Arithmetic

DrScheme looks like this:

 [init-screen.gif] 

Beware! If your window does not say Language: Beginning Student in the lower window like the above picture, then see the IMPORTANT note in Preparing DrScheme.

The top area, the definitions window, is for defining new programs. We'll explain how to use this window later, in Variables and Programs.

To type Scheme numbers into DrScheme, first click in DrScheme's bottom area, the interactions window, to set the keyboard focus to a point after the ``> '' prompt.

Beware! The insertion caret (the focus point for typing) must be placed after the space following the last ``>'' in the window; otherwise, DrScheme won't let you type a new expression. You can still select old expressions and results for copying, but they cannot be modified.

After typing a Scheme expression, type ENTER (a.k.a. RETURN). If you type a number, DrScheme echoes the number back. If you type a more complex expression, DrScheme prints the expression's value. For example, evaluating (+ 5 5) in DrScheme looks like this:

 [interactive.gif] 

Numbers

Scheme numbers are printed in the standard way, but spaces are not allowed within a number. Thus, -5, with no space between the - and 5, is the negative integer -5. But - 5, with a space in between, is two separate expressions: the minus operator and the number 5. Similarly, 3/2 is the fraction 3/2, while 3 / 2 is three separate expressions: the number 3, the division operator, and the number 2.

There is no limit on the size of exact numbers in Scheme. Try giving DrScheme the number 123456789012345678901234567890.

Try the number 10/12. DrScheme echoes back the repeating decimal 0.83 with a line over the 3. If you right-click the number (Mac OS: control-click), then you can choose to display the number in fraction form, 5/6. Note that DrScheme automatically puts the displayed fraction in its simplest form.

DrScheme also accepts decimal numbers, such as 3.2, and treats them in the same way as fractions.

To change the default method for printing numbers (fractions versus decimals), open the Choose Language dialog, click the Show Details button, and adjust the Fraction Style setting.

DrScheme always prints inexact results with a leading #i to alert you that the number is inexact. For example, an abbreviation for pi (the ratio between a circle's circumference and diameter) is built into DrScheme, and the input pi produces the output #i3.14159 (perhaps with more digits).

For the Especially Curious: Inexact numbers have a limited size as well as a limited precision. Thus, (expt #i2 #i5000) calculates the inexact value of 25000 to be #i+inf.0, which means ``roughly infinity'' -- very inexact, indeed!

Numeric Expressions

Every numeric expression that is not a number must start with an open parenthesis ( and end with a close parenthesis ). If, instead of (+ 1 2), you type + 1 2 or 1 + 2, DrScheme echos back each of the three separate pieces: 1, +, and 2.

Beware! If you type an open parenthesis without a matching close parenthesis (or vice versa), DrScheme does not even try to evaluate the malformed expression; instead, typing ENTER creates a new line for typing.
To help you match parentheses, DrScheme highlights parenthesis-balanced expressions with a gray background when the insertion caret is immediately before an open parenthesis or after a close parenthesis. However, this highlighting is only an indicator. The highlight does not actually select any text; in particular, the copy and cut commands do not apply to the highlighted region. The normal caret, which is used to select text for cut and paste poerations, is still visible as a blinking black line on the end of the highlighted region.

If a numeric expression starts with an open parenthesis, an operator must follow the parenthesis. Unlike arithmetic, where extra parentheses are always allowed, extra parentheses are illegal in a Scheme expression. Thus, (1) is not a numeric expression, neither is (+ (1) 2), and neither is ((+ 1 2)). If you give DrScheme the expression (1), it replies with the error ``First term after parenthesis is illegal in an application.'' In other words, since 1 appears after the parenthesis, DrScheme thinks you want to apply the ``operator'' 1 to some arguments. But 1 is not an operator, so it is illegal for 1 to follow an open parenthesis. DrScheme gives the same error message for ((+ 1 2)) because (+ 1 2) is also not an operator.

When typing a compound expression, you may accidentally omit a set of internal parentheses. In this case, DrScheme may report an error that a primitive operation was received when a number was expected. For example:

> (* (+ 2 - 4 5) 43 5)
+: expects type <number> as 2nd argument; given -; other
arguments were: 2 4 5

When an error occurs, DrScheme highlights the erroneous expression in pink. In the above example, (+ 2 - 4 5) is highlighted, pinpointing the specific part of the expression that contained the error: parentheses are missing around the sub-expression - 4 5.

An expression like (+ 1 2 3) does not signal an error because the standard arithmetic operations accept more than two arguments. (+ 1 2 3) is legal Scheme notation for 1 + 2 + 3, (- 1 2 3) means (1 - 2) - 3, (* 1 2 3) means 1 * 2 * 3, and (/ 1 2 3) means (1 / 2) / 3.

Stepping

DrScheme provides a Step tool that shows how a complex expression is evaluated, step-by-step. For example, given the expression

(+ 2 (* 3 4))

DrScheme must evaluate the (* 3 4) expression first to get 12. Then, it can evaluate (+ 2 12) to get 14.

To use the Step tool, put the expression(s) you want to evaluate into DrScheme's top area, the definitions window, then click the Step button:

 [prepare-to-step.gif] 

When you click Step, a new window appears with three parts:

 [stepper.gif] 

If you change the content of the definitions window, you must close the current stepper window and click Step again to step through the new expression.

2.2  Variables and Programs

Type program definitions in DrScheme's top area, the definitions window, like this:

 [using-defns.gif] 

After the definition is complete, click the Execute button. DrScheme creates a new prompt in the bottom window and starts evaluating expressions from the definitions window. If there are no errors in the definitions window, then the defined program can be tested the interactions window at the prompt. If there are errors in the definitions window, an error message is printed in the interactions window and the offending expression is highlighted with pink in the definitions window. After fixing an error in the definitions window, click Execute again.

After your program has been executed, evaluate test expressions in the interactions window, e.g., (area-of-disk 3). Test expressions can also appear in the definitions window. In this case, when the Execute button is clicked, the value of each test expression is displayed in the interactions window.

If the definitions window is modified and you type an expression into the interactions window without clicking Execute, DrScheme warns you that Execute is needed. If you do not click Execute, tests evaluated in the interactions window use programs from the previous Execute.

Don't forget to save your work. When the definitions window is modified, a Save button appears in the top left corner of DrScheme's window. Click the button to save your definitions to a file, and use the filename extension ``.scm'' for definition files.

The Shape of Definitions

The location of parentheses in a definition must match the following pattern exactly:

 .-- start definition
|
|         .-- start program and input names
|        |
|        |        .- end input names
v        v        v
(define (f arg ...)
  expression)
            ^- end definition

Compare this pattern to the area-of-disk program:
(define (area-of-disk r)
  (* 3.14 (* r r)))

In area-of-disk, the expression is (* 3.14 (* r r)). No extra parentheses are added to this expression.

If the parentheses for define are not correct, DrScheme reports the error ``Malformed define''. When this error occurs, check that a single set of parentheses surrounds the program name and argument list, and that a single body expression is provided (perhaps with its own set of parentheses, but with no extra parentheses).

The following is not a legal definition in the Beginning Student language level:

(define (f) expr)

because no arguments have been specified. (If DrScheme accepts this definition, double-check that the current language level is Beginning Student; see Preparing DrScheme).

Formatting Definitions

DrScheme helps you format your definitions in a standard, easy-to-read way. After typing the first line of a definition:

(define (area-of-disk r)

when you type ENTER, DrScheme automatically inserts some space at the beginning of the next line. Whenever the indentation of a line is incorrect, typing TAB with the caret anywhere in the line re-indents the line. Multiple lines can be reformatted by selecting the lines and typing TAB. DrScheme's Scheme|Indent All menu item reformats everything in the program window.

After a while, you will become used to the standard way of formatting definitions and expressions. When ENTER or TAB does not produce the indentation you expect, check the expression to make sure that parentheses are inserted at the right places. Strange indentation is a sign that your expression has the wrong shape.

Variable Names

Unlike most programming languages, program and variable names in Scheme can contain almost any character. For example, the following are legal names:

a-b    in->ft    my-2nd-program     positive?    [email protected]$%^&/*~program 

The name a-b does not mean a minus b; it's just a name. Even *3.14 is a name. Suppose that you forget the space between * and 3.14 when defining area-of-disk:
(define (area-of-disk r)
  (*3.14 (* r r)))

When you test this definition of area-of-disk, DrScheme reports that the name *3.14 is undefined.

Avoid the following characters in variable names:

"   '   `   ,   #   ;   |   \ 

Since quotes cannot be used in names, do not attempt to use x' as ``x prime.'' The pairs of bracket characters [ ] and { } are also special: they act just like parenthesis pairs ( ).

Names are case-sensitive, i.e., an upper-case letter is treated different from a lower-case letter in a name. For example, the name area-of-disk is different from the name Area-Of-Disk.

Interactions Window Tips

When you click the Execute button, the interactions window is cleared, but your old test expressions are not lost. In the interactions window, typing ESC-P copies the most recent test expression to the current prompt. (``ESC-P'' means ``push the ESC key, let go, and then push the p key''.) Typing ESC-P multiple times produces older and older expressions from the history of interaction expressions, while ESC-N produces newer expressions. Alternatively, place the insertion caret at the end of any old expression in the interactions window and type ENTER to copy the expression down to the current prompt. Of course, cut and paste work as usual.

Exercise Notes

Exercise 2.2.1 To use the convert.ss teachpack in DrScheme, choose the Language|Add Teachpack menu item. The file dialog starts in the teachpack directory of the plt installation directory. From there, go into the htdp directory and select the file convert.ss.

After clicking Execute, the definitions window shows convert.ss in its header, indicating that the teachpack is loaded. You must click the Execute button after selecting the teachpack before using it (otherwise DrScheme warns you that ``the program has changed,'' meaning that a different teachpack is now used by the program).

A teachpack extends the set of built-in operations and programs provided by DrScheme. After the convert.ss teachpack is selected, DrScheme provides the convert-gui, convert-repl, and convert-file programs.

More than one teachpack can be loaded at a time. The current set of teachpacks is stored as a preference, so even if you quit and restart DrScheme, the selected set is preserved. If you open multiple windows in DrScheme, the teachpack selection applies to all windows.

DrScheme's Language menu provides a menu item for each selected teachpack that clears it from the selected set, plus a Clear All Teachpacks menu item for clearing the entire set.

Exercise 2.2.5 Scheme has a built-in square operator. In futrure versions of DrScheme (startign with version 200), the operator's name will change to sqr.

2.3  Word Problems - no notes

No DrScheme notes for this section.

2.4  Errors

When an error occurs, DrScheme highlights the source of the error, whether it is in the definitions window or the interactions window. For example, typing (/ 1 0) in the interactions window causes that expression to be highlighted (and also produces the error message ``/: division by zero'').

Exercise Notes

Exercise 2.4.1 If DrScheme gives the error message ``procedure application: expected procedure'' for the expression (+ (10) 20) make sure that the language level is set to Beginning Student, as described in Preparing DrScheme. The correct error message is more specific: ``First term after parenthesis is illegal in an application''.

2.5  Designing Programs

Contracts are specified in the following format:

;; program : input1 input2 ... -> output

but DrScheme cannot check the format of your contracts. In Scheme, a semi-colon ; starts a comment that extends to the next linefeed (i.e., the end of the line if the program text is not automatically line-wrapped). DrScheme ignores anything between the first semi-colon in a line and the end of the line.

DrScheme can insert semi-colons at the start of lines for you. Select all of the lines to be ``commented out'' and select the Scheme|Comment Out menu item. Leading semi-colons are removed from all selected lines by the Scheme|Uncomment menu item.

You can also write a contract inside a text box. To insert a text box into your program, choose the Edit|Insert Text Box menu item. It inserts a text box wherever the caret is sitting.

Beware! If you use text boxes to enter contracts, DrScheme saves your program file in a special format, instead of the normal text format. Only DrScheme can read this special format.
Unlike comments, a text box is not ignored by DrScheme. Instead, it acts like a constant expression (just like a number), so DrScheme shows contract text boxes at the top of the interactions window when Execute is hit. (DrScheme does not look inside the text box, so don't put definitions or test expressions there.) Many programmers find these contracts in the interactions window useful as a summary of the programs in the definitions window. If you prefer, insert a single semi-colon before a text box (making it a comment) to prevent it from appearing in the interactions window.

In addition to line-based comments using ;, DrScheme ignores block comments starting with #| and ending with |#:

#| This is a
   multi-line
   block comment. |#

Block comments using #| and |# can be nested.

For the testing phase, a useful trick is to move the commented-out examples below the program definition, uncomment them, and put quotes around the = intact between the test expression and its result. Then, when you click Execute DrScheme will run all the tests, printing the actual result, a "=" (read as ``should be equal to''), and the expected result. For example,

(define (plus-ten n)
  (+ n 10))
;; Tests:
(plus-ten 4) "=" 14
(plus-ten -4) "=" -6 ;; oops!

produces the output
14
"="
14
6
"="
-6

in the interactions window when Execute is clicked. We can quickly see in the output that 6 is not -6, so either the program or the test case must be wrong. The string "should be" is often better than "=", since it clarifies which is the program result and which is the predicted result.

Test cases written as above must follow the program being tested. However, program implementors should always create the test cases as examples, before the program is written.