(in-package #:chatikbot) (defvar *backoff-start* 1 "Initial back-off") (defvar *backoff-max* 64 "Maximum back-off delay") (defun loop-with-error-backoff (func) (let ((backoff *backoff-start*)) (loop do (handler-case (progn (funcall func) (setf backoff *backoff-start*)) (condition (e) (log:error e) (log:info "Backing off for" backoff) (sleep backoff) (setf backoff (min *backoff-max* (* 2 backoff)))))))) (defun replace-all (string part replacement &key (test #'char=)) "Returns a new string in which all the occurences of the part is replaced with replacement." (with-output-to-string (out) (loop with part-length = (length part) for old-pos = 0 then (+ pos part-length) for pos = (search part string :start2 old-pos :test test) do (write-string string out :start old-pos :end (or pos (length string))) when pos do (write-string replacement out) while pos))) (defmacro aget (key alist) `(cdr (assoc ,key ,alist :test #'equal)))