Range Over Built in Lisp

Our first program will demonstrate iterating over built-in types using range. Here’s the full source code translated into Lisp.

(defun main ()
  ;; Sum numbers in a list
  (let* ((nums '(2 3 4))
         (sum 0))
    (dolist (num nums)
      (incf sum num))
    (format t "sum: ~d~%" sum))

  ;; Example of getting index while iterating
  (let ((nums '(2 3 4)))
    (loop for num in nums
          for i from 0
          when (= num 3)
          do (format t "index: ~d~%" i)))

  ;; Iterating over key/value pairs in a hash table
  (let ((kvs (make-hash-table :test 'equal)))
    (setf (gethash "a" kvs) "apple")
    (setf (gethash "b" kvs) "banana")
    (maphash (lambda (k v)
               (format t "~a -> ~a~%" k v))
             kvs))

  ;; Iterating over just the keys of a hash table
  (let ((kvs (make-hash-table :test 'equal)))
    (setf (gethash "a" kvs) "apple")
    (setf (gethash "b" kvs) "banana")
    (maphash (lambda (k _)
               (format t "key: ~a~%" k))
             kvs))

  ;; Iterating over Unicode code points in a string
  (let ((str "go"))
    (loop for c being the elements of str
          using (index i)
          do (format t "~d ~d~%" i (char-code c)))))

To run the program, ensure you have a Lisp interpreter (like SBCL), save the code in a file (e.g., range-example.lisp), and use the Lisp interpreter to execute it.

$ sbcl --script range-example.lisp
sum: 9
index: 1
a -> apple
b -> banana
key: a
key: b
0 103
1 111

This translation covers iterating over lists (slices and arrays), hash tables (maps), and strings, showcasing Lisp’s capabilities for these operations. Let’s delve deeper into the language to understand more of its features.