Approximate overview
Note: For mentor sessions, I’d like reflections and not just “this is what we did.
Write programs that produce unpredictable output.
Grinnell has suggested that we make up “random ids” for the students in our classes that we can use in online platforms.
Write a procedure, (random-id), that creates a string consisting of a random six-letter identifier of the form consonant-vowel-consonant-vowel-consonant-vowel, with all letters uppercase.
> (random-id)
"PALEQO"
> (random-id)
"ZEDUMI"
Isn’t that fun?
One of the points of the int-list->string exercise was that printing
of lists is optimistic in Racket. We assume we have a list until
proven otherwise.
We’ll use a local helper rather than the separate procedure. To
define local recursive helpers, we use letrec rather than `let.
(The reason is complicated.)
I’m using cond rather than if because I expect to add more cases.
(define int-list->string
(letrec ([; helper is used for all but the car; it add spaces and values
helper
(lambda (val)
(cond
[(null? val)
""]
[else
(string-append " "
(number->string (car val))
(helper (cdr val)))]))])
(lambda (val)
(cond
[(null? val)
"()"]
[else
(string-append "("
(number->string (car val))
(helper (cdr val))
")")]))))
Next version: Add support for a dot at the end.
(define int-listish->string
(letrec ([; helper is used for all but the car; it add spaces and values
helper
(lambda (val)
(cond
[(null? val)
""]
[(number? val) ; ADDED
(string-append " . " (number->string val))] ; ADDED
[else
(string-append " "
(number->string (car val))
(helper (cdr val)))]))])
(lambda (val)
(cond
[(null? val)
"()"]
[else
(string-append "("
(number->string (car val))
(helper (cdr val))
")")]))))
Minor update: Allow it to handle integers as well as lists of integers.
(define int-thing->string
(letrec ([; helper is used for all but the car; it add spaces and values
helper
(lambda (val)
(cond
[(null? val)
""]
[(number? val)
(string-append " . " (number->string val))]
[else
(string-append " "
(number->string (car val))
(helper (cdr val)))]))])
(lambda (val)
(cond
[(null? val)
"()"]
[(number? val) ; ADDED
(number->string val)] ; ADDED
[else
(string-append "("
(number->string (car val))
(helper (cdr val))
")")]))))
Next variant: Add support for nested structures
(define int-thing->string
(letrec ([; helper is used for all but the car; it add spaces and values
helper
(lambda (val)
(cond
[(null? val)
""]
[(number? val)
(string-append " . " (number->string val))]
[else
(string-append " "
(int-thing->string (car val)) ; CHANGED
(helper (cdr val)))]))])
(lambda (val)
(cond
[(null? val)
"()"]
[(number? val)
(number->string val)]
[else
(string-append "("
(int-thing->string (car val)) ; CHANGED
(helper (cdr val))
")")]))))
Why do we use lists instead of vectors? Vectors seem much better.
Vectors have a fixed size; lists are easy to add elements to and remove elements from.
If you want to add one element to a vector, you need to build a new vector that is slightly larger and copy over all the values.
What chooses the vector size?
It’s either explicit or implicit from how you create the vector.
(make-vector 10 'a)is size 10
(vector 'a 'b 'c)is size 3
vectors.rktpg1260.txt too.There’s a diagram on the board that might help you understand better.
What do you expect this to give?
> (let* ([gibbon (list "a" "b" "c" "d")]
[hippo gibbon])
(let ([gibbon (cdr gibbon)])
(list gibbon hippo)))