This page is kept for historical purposes only. Please see the home page for my current situation. —Luca Saiu.

DLL: TP 1 - Scheme programming

Today you will get acquainted with Guile and the GNU/Linux environment, and you will start with some simple Scheme exercises.

When you work at the Institut Galilée labs, before starting, you have to execute the following line on every terminal you use:

source ~10706282/add-prefix ~10706282/usr
That is for using the software I have installed in my home directory on the machines at Institut Galilée; I don't have administrator privileges on the lab machines, so I have installed everything in my home directory.

Of course you don't need to do anything similar at home if you have installed everything correctly, because you are the administrator of your own machines.

You can find other practical suggestions at the bottom of this page.

Task 1: Ensure that Guile works on your machine

Ensure that Guile works on your machine. Enter Guile in interactive mode with the command line:

and run
      (+ 1 2)
The system should answer with
Exit Guile by typing Ctrl+D on an empty line. Open your favorite editor and write a file called first-test.scm in your working directory, containing the text:
      (+ 1 2) ;; this doesn't output anything if it's in a file
      (define x (+ 1 2)) ;; this doesn't output anything either
      (display (* x x)) ;; this prints the square of x
Enter your working directory. Now we will run Guile in non-interactive mode. Execute your file with the following command line:
      guile first-test.scm
Now let's intentionally introduce an error into the file. Add the following line to the file:
      (display (1 + 2)) ;; this is wrong
Try to run the file again:
      guile first-test.scm
Can you understand the error message? You should! If you can't understand it, ask me. Now, without modifying the file, run it again with the command line
      guile --debug first-test.scm
When you specify the --debug option Guile is slower, but it prints better error messages; in particular, you can see line and column number.

The function load allows you to load a Scheme file when you are in interactive mode or you are running another file. Let's try it. Enter Guile in interactive mode:

You are in interactive mode, so you should be able to compute directly in the interpreter:
      (* 5 6)
Comment out the wrong line in first-test.scm. Comments in Scheme start with ; and are terminated by the end of the line.
Now load the file from the interactive mode:
      (load "first-test.scm")
The file has been executed, and now for example you can use x, which was defined there:
      (* x x)
You can also exit Guile with the quit function. It's a function of zero parameters, so you have to call it like

Task 2: the average of two numbers

Define a function called average for computing the average (moyenne) of two numbers. You should write your function with an editor, save the file as average.scm and test it by running

      guile --debug average.scm
At the end of your file you can add one or more tests:
      (display (average 3 5)) ;; it should print 4
      (display (average 0 100)) ;; it should print 50
Call me if you have problems with this.

Task 3: the average of a list of numbers

Write a function called average-of-list computing the average of a list of numbers, and test it just like in the previous task.

      (display (average-of-list '(1 2 3 4))) ;; it should print 5/2

Task 4: simple recursive functions on lists

Task 5: higher-order function on lists

Write a function called my-map taking two parameters: another function of one parameter (let's call it f), and a list (let's call it xs). my-map should apply the given function f to all the elements of xs and return the list of results. my-map is the same as the predefined function map.

      (display (my-map zero? '(1 0 2 3 0 3 4))) ; it should print (#f #t #f #f #t #f #f)
You have understood that map is useful for doing things that you would do with loops in other languages. What if you are not interested in the list of results but you just want to apply the function to the elements, without building anything interesting? Write the function iterate, which does just that (iterate doesn't return anything interesting). For doing this you need the begin form (look it up in the documentation if I didn't explain it).
      (iterate display '(a b c d)) ; this should print abcd
Can you replace begin with something else in iterate? Tell me your solution.

Task 6: another nice higher-order function

Implement a function called derivative, taking another function and returning (an approximation of) its derivative.
Hints: use the mathematical definition of derivative, which you can find here. You must use lambda, and probably also let. Notice the parentheses in the following test code: derivative takes a function of one argument and returns another function of one argument.

      (display ((derivative sin) 0)) ; this should print a value near 1.0
      (display ((derivative (lambda (x) (* x x))) 1)) ; this should print a value near 2.0
Show me your code if you succeed in doing this.

Suggestions and Useful resources

Notes for myself, in case of problems with the SERCAL installation or with student accounts:
My id is 10706282 .

Back to my home page...

Luca Saiu
Last modified: 2011-09-20
Copyright © 2010 Luca Saiu
Verbatim copying and redistribution of this entire page are permitted provided this notice is preserved.