Exercise index of this lecture   Alphabetic index   Course home   

Exercises and solutions
Expressions, Types, and Functions


2.1   Getting started with Scheme and LAML * 

The purpose of this exercises is learn the most important practical details of using a Scheme system on Unix. In case you insist to use Windows we will assume that you install the necessary software in your spare time. There is no time available to do that during the course exercises. Further details on installation of Scheme and LAML on Windows.

You will have to choose between DrScheme and MzScheme.

DrScheme is a user friendly environment for creating and running Scheme programs, with lots of menus and lots of help. However, it is somewhat awkward to use DrScheme with LAML. Only use DrScheme in this course if you cannot use Emacs, or if you are afraid of textually, command based tools. Follow this link for further details.

MzScheme is the underlying engine of DrScheme. MzScheme is a simple read-eval-print loop, which let you enter an expression, evaluate and print the result. MzScheme is not very good for debugging and error tracing. MzScheme works well together with Emacs, and there is a nice connection between MzScheme and LAML. MzScheme used with Emacs is preferred on this course. Please go through the following steps:

  1. Insert the following line in your .emacs file in your home dir, and then restart Emacs:

      (load "/pack/laml/emacs-support/dot-emacs-contribution.el")

  2. Have a session with a naked Scheme system by issuing the following command in Emacs: M-x run-scheme-interactively

    • Define a couple of simple functions ( odd and even, for instance) and call them.

    • Split the window in two parts with C-x 2 and make a buffer in the topmost one named sources.scm ( C-x b ). Bring the Scheme interpreter started above into the lower part of the window. The buffer with the Scheme process is called *inferior-lisp*. Put the sources.scm buffer in Scheme mode ( M-x scheme-mode ). Define the functions odd and even in the buffer and use the Scheme menu (or the keyboard shortcuts) to define them in the running Scheme process.

  3. Have a similar session with a Scheme+LAML system by issuing the following command in Emacs: M-x run-laml-interactively (You may have to confirm that a previously started Scheme process is allowed to be killed).

    • All you did in item 2 can also be done here.

    • Evaluate a simple HTML expression, such as

            (html (head (title "A title")) (body (p "A body")))

    • Use the function xml-render to make a textual rendering of the HTML expression.

    • Make a deliberate grammatical error in the LAML expression and find out what happens.

  4. Make a file 'try.laml'.

    • Control that Emacs brings the buffer in Laml mode. Issue a M-x laml-mode explicitly, if necessary.

    • Use the menu 'Laml > Insert LAML template' to insert an XHTML template.

    • Fill in some details in the head and body.

    • Process the file via the LAML menu in Emacs: Process asynchronously. The file try.html will be defined.

    • Play with simple changes to the HTML expression, and re-process. You can just hit C-o on the keyboard for processing.

    • You can get good inspiration from the tutorial Getting started with LAML at this point.


2.2   Construction of symbolic expressions * 

Construct the symbolic expressions illustrated on this page via the cons primitive in Scheme. The entities named a through h should be symbols. As a help, the rightmost part of the structure is made by (cons 'g 'h). 'g is equivalent to (quote g), meaning that g is not evaluated, but taken for face value.

Experiment with h being the empty list. Try to use a proper list function, such as length, on your structures.

Solution

The following is a name binding form with the left and right branch of the structure:

(let ((left (cons (cons 'a 'b) (cons 'c 'd)))
      (right (cons (cons 'e 'f) (cons 'g 'h))))
  (cons left right))

It is, of course, also possible to make one nasty expression with cons'es:

(cons (cons (cons 'a 'b) (cons 'c 'd)) (cons (cons 'e 'f) (cons 'g 'h)))

Please notice the way the Scheme interpreter prints the value of the expression. Try find the rule it applies for printing.


2.3   Every second element of a list ** 

Write a function, every-second-element, that returns every second element of a list. As examples

  (every-second-element '(a b c)) => (a c)
  (every-second-element '(a b c d)) => (a c)

It is recommended that you formulate a recursive solution. Be sure to consider the basis case(s) carefully.

It is often worthwhile to go for a more general solution than actually needed. Sometimes, in fact, the general solution is simpler than one of the more specialized solutions. Discuss possible generalizations of every-second-element, and implement the one you find most appropriate.

Solution

;; Return every second element of list, starting with the first element.
;; This function is useful to extract the keys or values of a property list.
(define (every-second-element lst)
  (cond ((null? lst) '())
        ((null? (cdr lst)) (list (car lst)))
        (else (cons (car lst) (every-second-element (cddr lst))))))


2.4   Creation of association lists * 

Program a function pair-up that constructs an association list from a list of keys and a list of values. As an example

  (pair-up '(a b c) (list 1 2 3))

should return

  ((a . 1) (b . 2) (c . 3))

Think of a reasonable solution in case the length of the key list is different from the length of the value list.

Solution

; Return the association list formed by keys from key-list and values from value-list.
; Terminate when the shortest of the lists is exhausted.
(define (pair-up key-list value-list)
  (if (or (null? key-list) (null? value-list))
      '()
      (cons
       (cons (car key-list) (car value-list))
       (pair-up (cdr key-list) (cdr value-list)))))


2.5   Association list and property lists * 

Association lists have been introduced at this page. An association list is a list of keyword-value pairs (a list of cons cells).

Property lists are closely related to association lists. A property list is a 'flat list' of even length with alternating keys and values.

The property list corresponding to the following association list

  ((a . 1) (b . 2) (c . 3))

is

  (a 1 b 2 c 3)

Program a function that converts an association list to a property list. Next, program the function that converts a property list to an association list.

Solution

;; Make and return an association list from a property list plist.
(define (propertylist-to-alist plist)
  (let ((lgt (length plist)))
   (cond ((null? plist) '())
         ((= 1 lgt) (error "propertylist-to-a-list called with list of odd length. A property list is always of even length"))
         ((>= lgt 2) (cons (cons (car plist) (cadr plist)) (propertylist-to-alist (cddr plist)))))))

;; Make and return a property list from an association list.
(define (alist-to-propertylist alist)
  (cond ((null? alist) '())
        (else (cons (car (car alist)) (cons (cdr (car alist)) (alist-to-propertylist (cdr alist)))))))


2.6   Parameter passing in Scheme * 

Familiarize yourself with the parameter passing rules of Scheme by trying out the following calls:

  ((lambda (x y z) (list x y z)) 1 2 3)
  ((lambda (x y z) (list x y z)) 1 2)
  ((lambda (x y z) (list x y z)) 1 2 3 4)
  ((lambda (x y z . r) (list x y z r)) 1 2 3)
  ((lambda (x y z . r) (list x y z r)) 1 2)
  ((lambda (x y z . r) (list x y z r)) 1 2 3 4)
  ((lambda r r) 1 2 3)
  ((lambda r r) 1 2)
  ((lambda r r) 1 2 3 4)

Be sure that you can explain all the results


2.7   Colors in HTML ** 

In HTML we define colors as text strings of length 7:

    "#rstuvw"

The symbols r, s, t, u, v, and w are all hexadecimal numbers between 0 and f (15). rs is in that way the hexadecimal representation for red, tu is the code for green, and vw is the code for blue.

As an example, the text string

    "#ffffff"

represents white and

    "#ff0000"

is red.

In Scheme we wish to represent a color as the list

    (color r g b)

where color is a symbol, r is number between 0 and 255 which represents the amount of red, and g and b in a similar way the amount of green and blue in the color.

Write a Scheme function that transforms a Scheme color to a HTML color string.

It is a good training to program the function that converts decimal numbers to hexa decimal numbers. I suggest that you do that - I did it in fact in my solution! If you want to make life a little easier, the Scheme function (number->string n radix) is helpful (pass radix 16 as second parameter).

Solution

Please see the elucidative program for a solution.


2.8   Letter case conversion ** 

In many web documents it is desirable to control the letter case of selected words. This allows us to present documents with consistent appearances. Therefore it is helpful to be able to capitalize a string, to transform a string to consist of upper case letters only, and to lower case letters only. Be sure to leave non-alphabetic characters untouched. Also, be sure to handle the Danish characters 'æ', 'ø', and 'å' (ASCII 230, 248, and 229 respectively). In addition, let us emphasize that we want functions that do not mutate the input string by any means. (It means that you are not allowed to modify the strings passed as input to your functions).

Write functions capitalize-a-string, upcase-a-string, downcase-a-string for these purposes.

As examples of their use, please study the following:

    (capitalize-a-string "monkey") => "Monkey"

    (upcase-a-string "monkey") => "MONKEY"

    (downcase-a-string "MONkey") => "monkey"

Hint: I suggest that you program the necessary functions yourself. Convert the string to a list of ASCII codes, do the necessary transformations on this list, and convert the list of modified ASCII codes back to a string. The Scheme functions list->string and string->list are useful.

Hint: If you want to make life a little easier (and learn less from this exercise...) you can use the Scheme functions char-upcase and char-downcase, which work on characters. But these functions do maybe not work on the Danish letters, so you you probably need some patches.

Solution

Please see the elucidative program for a solution.


Generated: Tuesday July 2, 2013, 09:14:46