# Scheme language elements

## Comments

Comments are preceded by a semicolon (;) and extend for the rest of the line. NexJ Studio's scheme editor provides some useful shortcuts for working with comments. These include:

- Generate Element Comment: Alt+Shift+J
- Toggle Comment: Ctrl+Shift+/, which works with multi-line selections

`; this is a comment in scheme`

## Expressions and types

The simplest expressions are constant atomic symbols, numbers, Booleans, characters, strings, vectors, pairs, and lists.

Symbols, procedure and variable names are case-sensitive.

```
> "hello" ; constant string
; "hello"
> 12345.67 ; constant number
; 12345.67
> 'sym ; symbol
; sym
> '(a b c d e) ; list
; if we didn't have the ' that is, if the expression was "(a b c d e)", then 'a' would be evaluated as the function 'a' with arguments b c d and e.
; (a b c d e)
> '(a . b) ; pair
; each pair has a "head" (in this case a) and a "tail" (in this case b).
(a . b)
> #f ; boolean false - true is #t
; #f
```

The Boolean type represents true and false by #t and #f respectively. Any type can be used where a Boolean type is expected; any value other than #f is considered to be true, including the empty list.

Scheme uses a prefix notation. For example:

```
> (+ 3 4)
; 7
> (format "Mailbox {0} has {1} new messages." "shawed1" 55)
; "Mailbox shawed1 has 55 new messages."
> (string-upcase "shout")
; "SHOUT"
> (> 5 7)
; #f
```

Scheme's basic data structure is the list. Lists are really lists of pairs. A pair is written as `(val1 . val2)`

. A list is a linked list of pairs, ending in null. The equivalent notation for null is (). For example, `'("a" "b" "c")`

is really `("a" . ("b" . ("c" . ())))`

which also could be thought of as `("a" -> ("b" -> ("c" -> (emptyList))))`

. Lists are written as sequences of objects surrounded by parentheses.

```
> '("a" "b" "c") ; this is a quoted list, the ' is equvalent to quote. For example, (quote ("a" "b" "c"))
; ("a" "b" "c")
; The quote makes Scheme treat the list as data. Without the ' character, Scheme would try to treat "a" as a function and would throw an error.
```

There are many functions for manipulating lists, including accessors: getters `car`

and `cdr`

and setters `set-car!`

and `set-cdr!`

. The function `list-ref`

provides access to an arbitrary member of a list, `length`

gives its length, and the list constructor is `list`

. There are also procedures to reverse a list, to obtain the tail of a list, to check for list membership, and to perform key-value lookups (association lists).

```
> (car '(1 2 3)) ; get the head of the list (first pair)
; 1
> (cdr '(1 2 3)) ; get the tail of the list (first pair which returns the rest of the list)
; (2 3)
> (cdr '(1)) ; get the tail of the list (rest of the list in this case is null
; ()
> (cons '(1 2) '(3 4)) ; construct a new pair
; ((1 2) 3 4)
> (list '(1 2) '(3 4)) ; construct a list
; ((1 2) (3 4))
```

## Variables

Variables are dynamically typed and are bound to values by a `define`

, a `let `

expression, and a few other Scheme forms. Variables bound at the top level with a `define`

are in global scope.

`(define startTime (now))`

Variables bound in a `let `

are in scope for the body of the `let`

.

```
(let
((startTime (now)) (index 0))
...
; Scope of startTime and index.
...
)
```

A `let*`

expression is used when one of the declarations in a let depends on another.

```
(let*
((lowerBound 1) (upperBound (+ lowerBound 100)))
...
; Scope of lowerBound and uppderBound
; to start with lowerBound = 1 and upperBound = 101
...
)
```

## Functions

A *function* is a portion of code within a larger program that performs a specific task and is relatively independent of the remaining code. A function can take zero or more arguments, does some processing in its body and returns a result which is the return value of the last statement executed before exiting the body.

In Scheme, unnamed functions are created with the special keyword `lambda`

.

```
(lambda (x) (* x x)) ; create a function that takes a single argument.
; "lambda" is evaluated and returns a reference to a function that squares its input parameter
((lambda (x) (* x x)) 7) ; evaluate the head of the list, which returns a function, and apply that function to the parameter "7" -> 49
(define sq (lambda (x) (* x x))) ; create a variable "sq" and assign to it our squaring function
(sq 7) ; apply the function associated with the variable "sq" to the parameter "7" -> 49
```

Functions can be arguments to other functions and be returned by them. They can be assigned to variables and are created by lambda forms. For example:

Example 1

```
; Define a function called loadData with two arguments fileName and pageSize
; "..." represents the function body.
(define loadData
(lambda (fileName pageSize)
...
)
)
```

Example 2

```
; A shorter equivalent form to example 1.
(define (loadData fileName pageSize)
...
)
```

Example 3

```
; Shows how functions are applied
; The function being applied is in the first position of the list while the rest of the list contains the arguments
(loadData "NightlyBatch.csv" 500)
```

Example 4

```
; The apply function takes its first argument and applies it to a list of arguments, so the previous function call can also be written
(apply loadData (list "NightlyBatch.csv" 500))
```

In Scheme, functions are divided into two basic categories: procedures and intrinsics. All intrinsics are procedures, but not all procedures are intrinsics. Intrinsics are pre-defined functions in the Scheme language. These include +, -, *, /, set!, car, cdr, and other basic procedures.

```
> (define add3 (lambda (x) (+ x 3)))
; #<PCodeFunction:add3>
> (add3 4)
; 7
```

## Assignment

Assignments do not create new bindings, as with let or lambda, but rather change the values of existing bindings. Assignments are performed with set!.

```
> (define a 1)
; 1
> (set! a 2)
; 2
> a
; 2
```