Select in Lisp
Common Lisp doesn’t have built-in support for concurrent programming like Go’s goroutines and channels. However, we can use threads and queues to achieve similar functionality. Here’s an example that mimics the behavior of the original Go code:
(ql:quickload '(:bordeaux-threads :cl-cont))
(defpackage :select-example
(:use :cl :bordeaux-threads :cl-cont))
(in-package :select-example)
(defun main ()
;; For our example we'll select across two queues.
(let ((q1 (make-queue))
(q2 (make-queue)))
;; Each queue will receive a value after some amount
;; of time, to simulate e.g. blocking operations
;; executing in concurrent threads.
(make-thread
(lambda ()
(sleep 1)
(enqueue "one" q1)))
(make-thread
(lambda ()
(sleep 2)
(enqueue "two" q2)))
;; We'll use a loop to await both of these values
;; simultaneously, printing each one as it arrives.
(dotimes (i 2)
(select
((dequeue q1) (msg)
(format t "received ~a~%" msg))
((dequeue q2) (msg)
(format t "received ~a~%" msg))))))
(defun run-example ()
(time (main)))
;; Run the example
(run-example)
In this Lisp version:
We use the
bordeaux-threads
library for thread creation and thecl-cont
library for theselect
macro, which provides functionality similar to Go’sselect
.We define two queues
q1
andq2
instead of channels.We create two threads that sleep for 1 and 2 seconds respectively, then enqueue values to the queues.
We use a
dotimes
loop to dequeue values from both queues, similar to thefor
loop in the Go version.The
select
macro is used to wait on both queues simultaneously, printing each value as it arrives.
To run this program, you would typically save it to a file (e.g., select-example.lisp
) and load it into your Lisp environment. The output would be similar to:
Evaluation took:
2.002 seconds of real time
0.000078 seconds of total run time (0.000078 user, 0.000000 system)
0.00% CPU
5,662,627,592 processor cycles
32,768 bytes consed
received one
received two
Note that the total execution time is only about 2 seconds since both the 1 and 2 second sleeps execute concurrently.
This example demonstrates how to implement concurrent operations and selection between multiple sources in Common Lisp, achieving functionality similar to Go’s select statement and goroutines.