Created
June 16, 2026 17:07
-
-
Save jeroenvandijk/d0cbc94552025a189a1ae9fc8916223a to your computer and use it in GitHub Desktop.
Sandboxed re-matches in Babashka Sci on the JVM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;; Try with deps-try org.babashka/sci 0.13.52 (see https://github.com/eval/deps-try) | |
| ;; The following takes 6 seconds on my machine | |
| (time | |
| (re-matches #"^(.*a){20}$" (str (apply str (repeat 28 \a)) "!"))) | |
| ;; With Sci's new :interrupt-fn feature we can make regexp's safer: | |
| (require '[sci.ctx-store :as store] | |
| '[sci.core :as sci] | |
| '[sci.interrupt :as interrupt]) | |
| (deftype InterruptibleCharSequence [^CharSequence s interrupt] | |
| CharSequence | |
| (length [_] | |
| (.length s)) | |
| (charAt [_ i] | |
| (interrupt) | |
| (.charAt s i)) | |
| (subSequence [_ start end] | |
| (InterruptibleCharSequence. (.subSequence s start end) interrupt)) | |
| Object | |
| (toString [_] | |
| (.toString s))) | |
| (defn sci-re-matches [re s] | |
| (re-matches re | |
| (if-let [interrupt (interrupt/get-interrupt-fn (store/get-ctx))] | |
| (InterruptibleCharSequence. s interrupt) | |
| s))) | |
| (defn limit [n] | |
| (let [counter (atom 0)] | |
| (fn [] (when (> (swap! counter inc) n) | |
| (throw (ex-info "interrupted" {:type :interrupt})))))) | |
| ;; This will return quickly after reach 500 iterations | |
| (let [ctx (sci/init | |
| {:namespaces {'clojure.core (assoc interrupt/clojure-core 're-matches sci-re-matches)} | |
| :interrupt-fn (limit 500)})] | |
| (time (sci/eval-form ctx '(re-matches #"^(.*a){20}$" (str (apply str (repeat 28 \a)) "!"))))) | |
| ;; Whereas the following will not be interrupted and run for around 25 seconds | |
| (let [ctx (sci/init | |
| {:namespaces {'clojure.core (assoc interrupt/clojure-core 're-matches sci-re-matches)} | |
| :interrupt-fn (limit Long/MAX_VALUE)})] | |
| (time (sci/eval-form ctx '(re-matches #"^(.*a){20}$" (str (apply str (repeat 28 \a)) "!"))))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment