sci

2026-06-17T05:23:22.025489Z

We should probably not be able to catch the interrupt exception from within the code?

(sci/eval-string "(try (loop [] (recur)) (catch Exception ex :noop))" {:interrupt-fn (limit 100)})
;=> :noop

2026-06-17T05:30:28.716759Z

You cannot do much after I think, but it could hide the interrupt exception or it could be used to test the limits

borkdude 2026-06-17T06:28:53.534189Z

Yeah I think this should be considered a bug, issue welcome

borkdude 2026-06-17T06:29:54.605149Z

Throwing a special exception that is ignored in SCI or so can be a solution

borkdude 2026-06-17T09:27:04.926099Z

PSA: :interrupt-fn now requires you to use sci.interrupt/interrupt! to interrupt evaluation.

(require '[sci.interrupt :as interrupt])

(defn limit [n]
  (let [counter (atom 0)]
    (fn [] (when (> (swap! counter inc) n)
             (interrupt/interrupt!)))))
This solves the problem that a user cannot catch the exception thrown by the :interrupt-fn. Thanks @jeroenvandijk for reporting this problem. See updated docs. https://github.com/babashka/sci/blob/master/doc/interrupt.md cc @whilo

👏 1
2026-06-17T14:46:36.311579Z

Ok curious what you think about the following below (from https://github.com/babashka/sci/pull/1027)

;; Try the following
;;
;;   deps-try  instance-methods-control-exp

(require '[sci.core :as sci]
         '[sci.interrupt :as interrupt])

(defn pow'
  [x exponent]
  (when (neg? exponent)
    (throw (ArithmeticException. "negative exponent")))
  (loop [e exponent
         base (bigint x)
         acc  1N]
    (interrupt/interrupt!)
    (if (zero? e)
      acc
      (recur (quot e 2)
             (*' base base)
             (if (odd? e)
               (*' acc base)
               acc)))))

(time
  (try
    (sci/eval-string "(.pow (biginteger 10) 10000000)"
                     {:classes {'java.math.BigInteger {:instance-methods {'pow pow'}}}})
    (catch Exception e
      (println (ex-message e)))))

;; Interrupted
;; "Elapsed time: 1.602208 msecs"
;; => nil

2026-06-17T14:54:29.031139Z

Ok curious what you think about the following in this thread (from https://github.com/babashka/sci/pull/1027)

2026-06-17T14:55:28.042329Z

;; Try the following
;;
;;   deps-try  instance-methods-control-exp

(require '[sci.core :as sci]
         '[sci.ctx-store :as store]
         '[sci.interrupt :as interrupt])

(defn pow'
  [x exponent]
  (let [interrupt-fn (or (interrupt/get-interrupt-fn (store/get-ctx)) (constantly nil))]
    (when (neg? exponent)
      (throw (ArithmeticException. "negative exponent")))
    (loop [e exponent
           base (bigint x)
           acc  1N]
      (interrupt-fn)
      (if (zero? e)
        acc
        (recur (quot e 2)
               (*' base base)
               (if (odd? e)
                 (*' acc base)
                 acc))))))

(defn time-limit [ms]
  (let [deadline (+ (System/nanoTime) (.toNanos java.util.concurrent.TimeUnit/MILLISECONDS ms))]
    (fn []
      (when (> (System/nanoTime) deadline)
        (interrupt/interrupt!)))))

(time
  (try
    (sci/eval-string "(.pow (biginteger 10) 10000000)"
                     {:interrupt-fn (time-limit 100)
                      :classes {'java.math.BigInteger {:instance-methods {'pow pow'}}}})
    (catch Exception e
      (println (ex-message e)))))

;; Interrupted
;; "Elapsed time: 139.687542 msecs"
;; => nil