Timers in Scheme

(import (chicken time)
        (chicken format))

(define (main)
  ; Timers represent a single event in the future. You
  ; tell the timer how long you want to wait, and it
  ; provides a way to be notified at that time.
  ; This timer will wait 2 seconds.
  (define timer1 (make-timer 2))

  ; The following line blocks until the timer fires.
  (timer-wait! timer1)
  (print "Timer 1 fired")

  ; If you just wanted to wait, you could have used
  ; `thread-sleep!`. One reason a timer may be useful is
  ; that you can cancel the timer before it fires.
  ; Here's an example of that.
  (define timer2 (make-timer 1))
  (define timer2-thread
    (thread-start!
     (lambda ()
       (timer-wait! timer2)
       (print "Timer 2 fired"))))

  (timer-cancel! timer2)
  (print "Timer 2 stopped")

  ; Give timer2 enough time to fire, if it ever
  ; was going to, to show it is in fact stopped.
  (thread-sleep! 2))

(main)

This Scheme code demonstrates the use of timers, which are similar to the timers in the original example. Here’s a breakdown of the translation:

  1. We import the necessary modules: (chicken time) for timer operations and (chicken format) for printing.

  2. The main function is defined to encapsulate our code.

  3. We create timer1 using make-timer with a 2-second delay.

  4. We wait for timer1 to fire using timer-wait!, then print a message.

  5. For timer2, we create a timer and a separate thread that waits for the timer.

  6. We immediately cancel timer2 using timer-cancel! and print a message.

  7. We use thread-sleep! at the end to give timer2 time to fire if it was going to.

Note that Scheme doesn’t have built-in channels like Go, so we use threads to simulate concurrent behavior. The timer-wait! function blocks until the timer fires, similar to receiving from a channel in Go.

To run this program, you would save it to a file (e.g., timers.scm) and run it using a Scheme interpreter that supports the CHICKEN Scheme extensions, like so:

$ csi timers.scm
Timer 1 fired
Timer 2 stopped

The output shows that the first timer fires after about 2 seconds, while the second timer is stopped before it has a chance to fire.