Skip to content

Instantly share code, notes, and snippets.

@aymanosman
Last active March 28, 2023 16:17
Show Gist options
  • Save aymanosman/1adef69884d3739e0a8147ef92002dcf to your computer and use it in GitHub Desktop.
Save aymanosman/1adef69884d3739e0a8147ef92002dcf to your computer and use it in GitHub Desktop.
Restarts in Common Lisp
;; https://github.com/ocaml-multicore/ocaml-effects-tutorial/blob/master/sources/input_line_eff.ml
(define-condition conversion-failure (error)
((string :initarg :string))
(:report (lambda (condition stream)
(format stream "Conversion failure ~S" (slot-value condition 'string)))))
(defun int-of-string (string)
(handler-case
(parse-integer string)
(sb-int:simple-parse-error ()
(error 'conversion-failure :string string))))
(defun sum-up (acc count)
(let ((l (restart-case (read-line)
(return-values ()
(return-from sum-up (values acc count))))))
(restart-case
(sum-up (+ acc
(restart-case
(int-of-string l)
(use-value (v)
v)))
(1+ count))
(skip ()
(sum-up acc count)))))
(defun skip ()
(invoke-restart 'skip))
(defun return-values ()
(invoke-restart 'return-values))
(defun main ()
(format t "Starting up. Please input:~%")
(handler-bind ((conversion-failure
(lambda (condition)
(format *error-output* "~A~%" condition)
(skip)))
(end-of-file
(lambda (condition)
(declare (ignore condition))
(return-values))))
(multiple-value-bind (acc count) (sum-up 0 0)
(format t "Average is ~D~%" (/ acc count)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment