# Introduction to Scheme II: Basic Concepts

### References

• Index of JLIB Primitives.
• Index of Scheme Primitives.
• The JScheme homepage
• The Scheme Homepage
• The R4RS Scheme Manual

# Scheme Expressions and Java Values

The Scheme interpreter can be viewed as a kind of symbolic calculator that allows you to interactively evaluate expressions to get values. In this section we explore this view of Scheme as a fancy calculator. In particular, we examine the kinds of objects that Scheme is able to manipulate, the operations it is able to perform, and the way in which you can use the "define" expression to name new objects, and the "lambda" expression to create functions. You can try out the scheme code using the interpreter applet below (which detaches from the page for those who want it in a separate window).

## Constants

Scheme allows you to work with a variety of values. We provide a brief overview here. For more details, you can look over the full Jscheme documentation for constants. . There are several basic types of values that Jscheme manipulates: numbers, characters, strings, symbols, booleans, and Java objects. Each of which is described below. are

• numbers -- which can be integers or decimal numbers. When you type a number into the Scheme interpreter it usually simply echos it back, as the following examples illustrate.  ``` 1729 ; --> 1729 0.00390625 ; --> 0.00390625 ```
In some cases, Jscheme is not able to store the number precisely as you entered it, since it uses a limited amount of space to store integer and decimal numbers. In such a case, it may truncate long decimals.  ``` 2.7182817284590452353602874713526624977 ; --> 2.7182817284590453 ```
It may also switch to scientific notation for large (or small numbers).  ``` 10000000.0 ; --> 1.0E7 ```
where the suffix "E7" means that decimal point should be shifted 7 places to the right (i.e. the number should be multiplied by 107).

• characters -- which are single letters in the alphabet of the current locale (latin letters in the U.S., latin, hirogana, katakana, and Kanji in Japan). A character is specified using a hash sign (#) followed by the character surrounded by single quotes. the form:  ``` #'a' ; --> a ```
One can also specify general unicode characters using the notation `#'\uXXXX'`.

• strings -- which are sequences of characters that must always be enclosed in double quotes, must fit on one line, and must not contain any double quotes, e.g., ` "Hello World" "result" "window" "1789"` The Scheme interpreter will simply echo these back to you:  ``` "This sentence is false" ; --> "This sentence is false" ```

• boolean or "true/false" values -- Scheme uses ` #t ` for true and ` #f ` for false.  ``` #t ; --> #t ```

• symbols -- which are like strings but are either unquoted or are preceded by a single quote and generally begin with a letter and contain only letters and digits, but some kinds of punctuation can also be included, e.g.,  ``` 'window ; --> window 'value5 ; --> value5 '@*&!\$ ; --> @*&!\$ + ; --> {silk.Primitive +[0,n]} sin ; --> {silk.Primitive sin[1]} ```
If a symbol is not quoted, then the Scheme interpreter assumes it is a variable (see below) and tries to look up its value. Jscheme predefines the values of many symbols. There are two types of predefined symbols -- the Scheme primitives, and the Java literals.

• Scheme primitives. Scheme has a rich set of built-in functions, including all of the arithmetic functions: ` + - * / log exp sin cos tan ... `  ``` (+ 1 2 3 4 5) ; --> 15 (cos (acos 1.0)) ; --> 1.0 (exp (log (exp 1))) ; --> 2.718281828459045 (string-append "This sentence" " is false") ; --> "This sentence is false" (not #t) ; --> #f ```
For a complete list of the predefined Scheme Symbols see the complete index of Scheme primitives.

• Java literals. All Java literals contains either a "." or "\$" somewhere in their name. They are formed by taking full Java members names and possibly adding a "." or "\$" at the beginning or end, depending on what type of the particular Java member. For example, buttons, windows, colors, and big integers can be constructed and manipulated using the following expressions involving only Java literals and constants:  ``` (define b (java.awt.Button. "Do Not Push")) ;; create a button (define w (java.awt.Frame. "WARNING")) ;; create a window (define c (java.awt.Color. 255 200 145)) ;; create a color (.add w b) ;; add button to window (.setBackground w c) ;; change color of window to c (.pack w) (.show w) ;; select best window size at make it appear (define tento25 ;; create a big whole number (java.math.BigInteger. "10000000000000000000000000")) (define google (.pow tento25 4)) ;; raise it to the fourth power ```
There are literally thousands of Java literals which are available in the standard Java libraries, but we will only use a few in this course. If you are a Java programmer, you can write your own Java classes and access them through the same Java literal syntax as is used with the standard Java libraries. The particular collection of Java literals you have access to depends on the version of Java that is running the Jscheme interpreter, and on any Java classes that have been defined locally.

For a complete list of the Java 1.3 Standard Edition primitives (all of which are directly accessible from Jscheme), see the index of all Java 1.3 (Standard Edition) members of the 1840 Java classes. For a precise explanation of the Jscheme syntax for Java literals see the Java Literals page of the Jscheme documentation.

## JLIB

The version of Scheme we use in this class differs from most other implementations of Scheme in that it has been written in Java (which is why it can be run directly from your browser) and it provides access to a fairly large set of Java primitives which are not part of standard Scheme. It also provides a library of graphical user interface building tools. This library is called JLIB and has been written in Jscheme. Click here for a list of the JLIB primitives.

Recall, for example, the Hello.scm program we saw in the previous lecture:
 ``` (define win (window "Hello.scm" (label "HELLO WORLD!" red (CourierBold 60)))) (.pack win) (.show win) ```
This uses six Jlib primitives:

• `(window TITLE C)`
-- create a window of the specifed width, height, and title and add the component C to the window
• `(label TEXT COLOR FONT)`
-- create a label containging the given TEXT with the specified COLOR and FONT. The COLOR and FONT are optional attributes which can be in any order.
• `(CourierBold N)` -- create a bold face Courier font of size N.
• `red` -- the value of this symbol is the color "red"
• `(.pack WINDOW)` -- resize the window so it is as small as possible, but so that all components it contains are visible.
• `(.show COMPONENT)`
-- make the COMPONENT visible
This program also uses two integer constants (100, 200) and two string constants ("First Example" and "Hello World").

## Variables and Definitions

Scheme allows you to give store values in variables using the define statement. For example, to store the value 3.1415926 in the variable `pi`, you would evaluate the following expression:
 ``` (define pi 3.1415926) ```
If we then evaluate the symbol `pi`, the interpreter will write 3.1415926 in the Results textarea. We can also define new functions. For example, to define a square function you can use
 ``` (define square (lambda (x) (* x x))) ; --> square (square 55) ; --> 3025 ```
It would be clearer if we used "function" instead of "lambda"
 ``` (define square (function (x) (* x x))) ;; this is not valid scheme!!! ```
since that is the intended meaning, but the use of lambda has a long history which we honor by using it to define functions. An alternate approach to defining functions uses the following syntax in which the fact that "square" is a function definition is indicated by the presence of the parentheses around the function name and its argument: "square x".
 ``` (define (square x) (* x x)) ; --> square (square (square (square 2))) ; --> (square (square 4)) --> (square 16) --> 256 ```
Functions involving several variables can be just as easily defined
 ``` (define (area width height) (* width height)) ; --> area (area 9 11) ; --> 99 (define volume (lambda (width height depth) (* width height depth))) ; --> volume (volume 2 3 4) ; --> 24 ```

## Scheme Syntax

Syntax refers to the grammatical rules whereby one combines elements of a language to create valid expressions in that language. Scheme has relatively few syntactic rules.

We have seen two examples of scheme syntax so far. The main one is the application which allows us to apply functions to arguments:

 ``` (F A B ... C) ```
where F is an expression that evaluates to a function, and A, B, ..., C are expressions that evaluate to some values, and the function is then applied to those values.

There are about a dozen additional syntactic forms, which collectively are called the special forms. We have seen one already, the definition expression:

 ``` (define NAME EXPR) ```
This expression evaluates the expression EXPR to get a value which it then assigns to the variable NAME.

We now preview some of the most important special forms:

• Conditional evaluation:
```    ( if TEST THEN ELSE)
```
To evaluate this expression, we first evaluate the expression TEST. If it returns #t (the true value) then we evaluate the THEN expresssion, if it returns #f (the false value), then we evaluate the ELSE expression. For example, to evaluate the following expression  ``` (define dob 1982) (if (< (- 2000 dob) 21) "minors may not drink!!" "want a beer??") ```
we first evaluate `(- 2000 dob)` which returns 18, and then evaluate `(< 18 21)` which returns #t because 18 is less than 21. Since the test was true, we evaluate the THEN expression, which in this case is just the string "minors may not drink".

• Cond -- general conditional statemetn
```
(cond (Test1 value1)
(Test2 Value2)
...
(TestN valueN)
(else  defaultValue))
```
This expression is a generalized "if" statement. It applies several tests and returns the value corresponding to the first test which is not false. If all tests are false then the default value, specified by the final "else" clause, is used.

• Let -- local names
```
(let ((Name1 value1)
(Name2 Value2)
...
(NameN valueN))
Body)
```
This expression computes the names to the values and then uses these bindings to evaluate the body, which can consist of several expressions.