File ends

Write a function that prints the first and last lines in a file. These functions skip the printing part.

 $ cat hat.rkt 
 #lang racket 
 (require rackunit) 
 (define (hat1 f) 
   (let ((fst (read-line f))) 
     (if (eof-object? fst) 
       (let loop ((lst fst)) 
         (let ((l (read-line f))) 
           (if (eof-object? l) 
             (cons fst lst) 
             (loop l))))))) 
 (define (hat2 f) 
   (let ((lines (port->lines f))) 
     (if (null? lines) 
       (cons (car lines) (car (reverse lines)))))) 
 (check-equal? (hat2 (open-input-string "")) '()) 
 (define (test-it f) 
   (f hat1) 
   (f hat2)) 
  (lambda (f) 
    (check-equal? (hat1 (open-input-string "")) '()))) 
  (lambda (f) 
    (let ((p (f (open-input-string "hello\n")))) 
      (check-equal? (car p) "hello") 
      (check-equal? (cdr p) "hello")))) 
  (lambda (f) 
    (let ((p (f (open-input-string "hello\ngood-bye\n")))) 
      (check-equal? (car p) "hello") 
      (check-equal? (cdr p) "good-bye")))) 
  (lambda (f) 
    (let ((p (hat1 (open-input-string "red\nwhite\nblue\n")))) 
      (check-equal? (car p) "red") 
      (check-equal? (cdr p) "blue")))) 
 (define (time-it hat N f) 
   (let loop ((t 0) (n N)) 
     (if (= n 0) 
       (exact->inexact (/ t N)) 
       (let ((f (open-input-file f))) 
        (((a b c d) (time-apply hat (list f)))) 
          (loop (+ t b) (- n 1))))))) 
 (define (time n f) 
   (printf "hat1 ~a msec: ~a\n" f (time-it hat1 n f)) 
   (printf "hat2 ~a msec: ~a\n" f (time-it hat2 n f))) 
 (define N 10) 
 (time N "moby-dick.htm") 
 (time N "/usr/share/dict/words") 
 $ mzscheme hat.rkt  
 hat1 moby-dick.htm msec: 36.4 
 hat2 moby-dick.htm msec: 33.2 
 hat1 /usr/share/dict/words msec: 32.0 
 hat2 /usr/share/dict/words msec: 74.0