UNB/ CS/ David Bremner/ teaching/ cs2613/ labs/ Lab 4

# Part 1 Compare and Contrast

Time
15 minutes
Activity
Group discussion

For each of the following `racket` samples, what is the closest concept from `Java`, or roughly how would you do the same thing in `Java`? How are the two similar? How are they different? Try to classify differences as deep or shallow (completely subjective!)

1. `#lang racket`, `#lang slideshow`

2. `(+ 1 2)`

3. `(rectangle 10 10)`

4. `(define r 10)`

5. `(define (square x) (rectangle x x))`

6. `(colorize (square 10) "red")`

7. `(let* ([x 10] [y (+ x 10)]) (* x y))`

# Part 2 Functions as values

Time
15 minutes
Activity
Demo

Most of you probably read Part 6 of the Quick Tutorial because the function `series` defined there was used in part 7.

Let's try and reduce the repeated code in this definition.

```(define (series mk)
(hc-append 4 (mk 5) (mk 10) (mk 20)))
```

Initial attempt fails. What to add?

```(define (series2 mk)
(hc-append 4 (map mk '(5 10 20))))
```

This really starts to pay off with more repetition

```(define (series3 mk)
(apply hc-append 1 (build-list 100 mk)))
```

## Part 3 Recursion

Time
20 minutes
Activity
Small groups
• Form small groups to solve the following puzzles

• Fill in the missing expression for the recursive case of the factorial function

```    #lang racket
(define (fact n)
(cond
[(zero? n) 1]
[else                     ]))

(module+ test
(require rackunit)
(check-equal? (fact 10) 3628800))
```
• Use the debugger to find the bug in the following program
```    #lang racket
(define (list-length list)
(if (empty? list)
0
(+ 1 (list-length list))))

(module+ test
(require rackunit)
(define test-list '(1 2 3))

(check-equal? (length test-list) (list-length test-list)))
```

# Part 4 Scribble

Time
25 min
Activity
Demo/Group Discussion

Scribble is one of the markup languages supported by frog. It has the advantage of being easily extensible using Racket.

• As I work through the following demo, follow along on your own computer.

• Create a new blog entry with

``````  \$ raco frog -N "Scribble Demo"
``````
• What is the first line of the newly created file?

• What does that mean? Scribble is an example of a Domain Specific Language meant for producing documents.

• Scribble uses @ syntax That means we can use `@` like an escape back to normal racket syntex.

• The simplest form of this is to define abbreviations that expand to strings.
• A more interesting use is to define functions that can be invoked in the document. Here is the new syntax we want to support

``````@hello{}
``````

In both cases we need to define a function, which we can do by just putting `@` in front of a normal racket definition.

``````  @(define (hello) "hello")
``````
• Things become more useful when we use the existing scribble API. Suppose we want to make lots of lists like

• item 1
• item 2
• Here's a function to do generate the lists from syntax like `@todo["Shopping" "cheese" "fish" "shuriken"]`

```    @(define (todo hdr . lst) (list (bold hdr) (apply itemlist (map item lst))))
```
• Let's try the function out in our blog entry.

• Now let's try to understand what features of Racket and scribble it is using.

• [] vs {}

• what is '.' doing

• what are `itemlist` and `item`

# Part 5 Modules

Time
25 minutes
Activity
Individual

In Lab 2 we covered the Quick tutorial section on modules We've also been using modules as part of unit testing. In this section of the lab we we will further explore modules, submodules, `require` and `provide`.

• start the fcs-vm-cs2613-dev VM
• make a directory `labs/L04` inside your `~/fcshome/cs2613` git repository
• create `~fcshome/cs2613/labs/L04/hello.rkt` with the following content
```    #lang racket
(define (hello) (displayln "Hello world!"))
```
• You can test your new module by running `(hello)`
• Following the racket guide, replace `#lang racket` with a `(module …)` form
```    (check-equal? (with-output-to-string hello) "Hello world!\n")
```
• `check-equal?` is defined in the module `rackunit`, so to get the above to compile we need to `(require rackunit)`. Experiment a bit. Does it matter where you put `(require rackunit)`?

• For now just add this to the module body, don't create a test submodule. Temporarily replace `displayln` with `display` to see a familiar bug caught by our test.

• Make a second file in the same directory, call it `application.rkt`.

• in `application.rkt`, require your module "hello.rkt", and call '(hello)'

• This fails, because we didn't export any bindings from "hello.rkt". Add `(provide hello)`. Again, observe that it doesn't matter too much where you put it: order of definition is less important in Racket than in some languages. By convention, both `require` and `provide` should be at the top of the module (or submodule).

• Often unit tests can take a noticable amount of time, or require things like network access not necessarily available to an application. To simulate a long running test, use begin and `sleep`

```    (check-equal? (with-output-to-string hello) (begin (sleep 3) "Hello world!\n"))
```
• Notice now that running "application.rkt" takes a long time. Fix this using the `(module+ test …)` form we already used (leave the test body as is).

• compare running "application.rkt" and "hello.rkt" from the command line with "racket filename" and "raco test filename".

• We can see that just running "racket hello.rkt" doesn't seem to do much; it can be useful to have a module that acts a library (i.e. is loaded with `require`) and also as a program. Add a main submodule so that "racket hello.rkt" also invokes `(hello)`

• Commit and push your files from this section.