Escay

Scheme in 'Fixnum days'

This page shows some excercises I made for school. The exercises are part of the lessons in 'Programming Languages'. The lessons are in Dutch, more information can be found here. The exercises are based on the 'Teach Yourself Scheme in Fixnum Days' Tutorial.

Martijn Morriën, April 2002


Excercise 1
Show unlimited Hello World

(define
  (hello)
  (
    (display "Hello, World!")
    (newline)
    (hello)
  )
)

(begin (hello))
Output
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
..
..
.
.

Download file exercise1.scm


Excercise 2
Calculate the circumference of a triangle

(define omtrek
  (lambda (x1 y1 x2 y2 x3 y3)
    (+
      (zijdelengte x1 y1 x3 y3)     
      (+ 
        (zijdelengte x1 y1 x2 y2)
        (zijdelengte x2 y2 x3 y3)      
      )
    )
  )
)

(define zijdelengte
  (lambda (x1 y1 x2 y2)
    (begin 
      (sqrt
        (+
         (expt (- x1 x2) 2)
         (expt (- y1 y2) 2)
        )
      )
    )
  )
)

(begin 
  (omtrek 0 3 4 3 0 0)  
)
Output
12
Download file exercise2.scm


Excercise 3
Define list-minimum

(define (list-minimum list)
  (if (null? list)
     list
     (minimum (car list) (cdr list))
  )
)

(define (minimum first-element remaining-list)
   (if (null? remaining-list) 
       first-element
           (if (> first-element (car remaining-list)) 
               (minimum (car remaining-list)(cdr remaining-list))
               (minimum first-element (cdr remaining-list)))
   )
)

(begin 
   (list-minimum (list 12 90 34 23 9 10 80 66 38))
)
Output
9
Download file exercise3.scm


Excercise 4
Calculate shortest triangle side length

(define omtrek
  (lambda (x1 y1 x2 y2 x3 y3)
    (+
      (zijdelengte x1 y1 x3 y3)     
      (+ 
        (zijdelengte x1 y1 x2 y2)
        (zijdelengte x1 y1 x3 y3)      
      )
    )
  )
)

(define kortstezijde
  (lambda (x1 y1 x2 y2 x3 y3)
     (list-minimum (list (zijdelengte x1 y1 x2 y2) (zijdelengte x1 y1 x3 y3) (zijdelengte x2 y2 x3 y3)))
  )
)

(define zijdelengte
  (lambda (x1 y1 x2 y2)
    (begin 
      (sqrt
        (+
         (expt (- x1 x2) 2)
         (expt (- y1 y2) 2)
        )
      )
    )
  )
)

(define (list-minimum list)
  (if (null? list)
     list
     (minimum (car list) (cdr list))
  )
)

(define (minimum first-element remaining-list)
   (if (null? remaining-list) 
       first-element
           (if (> first-element (car remaining-list)) 
               (minimum (car remaining-list)(cdr remaining-list))
               (minimum first-element (cdr remaining-list)))
   )
)

(begin 
   (display (zijdelengte  0 0 0 3))     (newline)
   (display (zijdelengte  0 3 4 3))     (newline)
   (display (zijdelengte  0 0 4 3))     (newline)   
   (display (omtrek       0 0 0 3 4 3)) (newline)
   (display (kortstezijde 0 0 0 3 4 3)) (newline)
   (display (kortstezijde 0 0 10 1 4 5))   
)
Output
3
4
5
13
3
6.4031242374328485
Download file exercise4.scm


Excercise 5
Define a for loop macro

(define-macro for
  ; example:
  ; (for   i   5    (<= i 12) (++ i)  (the for part))
  (lambda (var init test     incr   . branch)
    ;The backquote (`) introduces a template for a list.
    ;The elements of the template appear precisely the same in the resulting list, 
    ;except when they are prefixed by a comma (`,') or a comma-splice (`,@')
    ; i=0
   `(let ((,var ,init))
      ;v=empty list
      (let v () 
        ;when or if (<= i 12) begin with branch, the body of the for loop end with (++i)
        ;(when ,test    (begin ,@branch ,incr (v)))
        (if ,test    
            ; if ok: do branch, increase var, start again on empty list
            (begin ,@branch ,incr (v))
            ; else
            (display "else (end of for loop)")
        )
      )
    )
  )
)

(define-macro ++
  (lambda (var)
   `(begin 
      (set! ,var (+ ,var 1))
	  ,var
	)
  )
)
(define-macro when
  (lambda (test . branch)
    (list 'if test
      (cons 'begin branch)
    )
  )
)

(begin 
  (for i 5 (<= i 12) (++ i)
     (display "Hello, World!")
     (display i)
     (newline)
  )
)
Output
Hello, World!5
Hello, World!6
Hello, World!7
Hello, World!8
Hello, World!9
Hello, World!10
Hello, World!11
Hello, World!12
else (end of for loop)
Download file exercise5.scm


Excercise 6
Define bubblesort

; for loop macro
(define-macro for
  (lambda (var init test     incr   . branch)
   `(let ((,var ,init))
      (let v () 
        (if ,test    
          (begin ,@branch ,incr (v))
        )
      )
    )
  )
) 

; ++ macro to increment a counter
(define-macro ++
  (lambda (var)
    `(begin 
       (set! ,var (+ ,var 1))
       ,var
     )
  )
)

; list-length calculates the length of the list
(define list-length
  (lambda (l)
    (let loop ((i 0) (l l))
      (if (null? l) i
         (loop (+ i 1) (cdr l))
      )
    )
  )
)

; list-set! sets the nth position of a list to object
(define list-set! 
  (lambda (ls n obj)
    (if (zero? n)
      (set-car! ls obj)
      (list-set! (cdr ls) (- n 1) obj)
    )
  )
)

; swap! swaps 2 elements in a list, given two indexes
(define swap!
  (lambda (lst s1 s2)
    (let ((temp (list-ref lst s1)))
      (list-set! lst s1 (list-ref lst s2))
      (list-set! lst s2 temp)
    )
  )
)

; bubblesort walks trough a list and sorts the elements
(define bubblesort
  (lambda (lst)
    (for j 0 (< j (list-length lst)) (++ j)    
      (for i 0 (< i (- (list-length lst) 1)) (++ i)
        (if (> (list-ref lst i) (list-ref lst (+ i 1)))
          (swap! lst i (+ i 1))
        )
      )    
    )
  )
)

; define a simple unordered list
(define x (list 22 12 3 4 16 8 7))

(begin 
  (display x)(newline)    
  (bubblesort x)
  (display x)(newline)    
)
Output
 (22 12 3 4 16 8 7)
 (3 4 7 8 12 16 22)
Download file exercise6.scm


Excercise 7
Read numbers from a textfile and use bubblesort to order them

(define sum-of-file
  (lambda (source-file-name lst)
    (let ((source (open-input-file source-file-name))) ; Open the file.
      (let loop ((next (read source)))  ; Try to read a number.
        (if (not (eof-object? next))
          ;if not end of file reached:
          (begin 
            (if (zero? (list-ref lst 0))
              ; if list is empty
              (begin
                (list-set! lst 0 next)
              )
              ; else
              (begin
                (add! lst next)
              )
            )
          )
          ; else
          ;(begin 
          ;  (display "end of file reached")(newline)         
          ;)
        )
        (if (eof-object? next)          ; If you get the end-of-file object,
            ;if
            (begin
              (close-input-port source) ; close the file
            )                           ; end
            ;else
            (loop (read source))        ; try to read another number,
        )                               ; and repeat the loop.
      )
    )
  )
)   

; list-length calculates the length of the list
(define list-length
  (lambda (l)
    (let loop ((i 0) (l l))
      (if (null? l) i
         (loop (+ i 1) (cdr l))
      )
    )
  )
)

; list-set! sets the nth position of a list to object
(define list-set! 
  (lambda (ls n obj)
    (if (zero? n)
      (set-car! ls obj)
      (list-set! (cdr ls) (- n 1) obj)
    )
  )
)

; add
(define (add! lst el)
  (if (null? (cdr lst))
    (set-cdr! lst (list el))
    (add! (cdr lst) el)
  )
)

; for loop macro
(define-macro for
  (lambda (var init test     incr   . branch)
   `(let ((,var ,init))
      (let v () 
        (if ,test    
          (begin ,@branch ,incr (v))
        )
      )
    )
  )
) 

; ++ macro to increment a counter
(define-macro ++
  (lambda (var)
    `(begin 
       (set! ,var (+ ,var 1))
       ,var
     )
  )
)

; swap! swaps 2 elements in a list, given two indexes
(define swap!
  (lambda (lst s1 s2)
    (let ((temp (list-ref lst s1)))
      (list-set! lst s1 (list-ref lst s2))
      (list-set! lst s2 temp)
    )
  )
)

; bubblesort walks trough a list and sorts the elements
(define bubblesort
  (lambda (lst)
    (for j 0 (< j (list-length lst)) (++ j)    
      (for i 0 (< i (- (list-length lst) 1)) (++ i)
        (if (> (list-ref lst i) (list-ref lst (+ i 1)))
          (swap! lst i (+ i 1))
        )
      )    
    )
  )
)

; define a list
(define x (list 0))

(begin 
 (display x)(newline)
 (sum-of-file "c:\bubble-input.txt" x)
 (display x)(newline)
 (bubblesort x)
 (display x)(newline)   
)
Output (with this file)
(0)
(22 34 10 9 8 33 24)
(8 9 10 22 24 33 34)
Download file exercise7.scm