   ([s start] (subs s start (erlang/size.e s)))
   ([s start end] (binary/part.e s start (- end start))))
 
+(defn regex? [x]
+  (and (tuple? x) (= (first x) :re_pattern)))
+
 (defn re-run
   "Runs the matching of the pattern over the string using the provided
   options."

(defn +
  "Returns the sum of nums. (+) returns 0. Does not auto-promote
  longs, will throw on overflow. See also: +'"
  {:inline (nary-inline 'add 'unchecked_add)
   :inline-arities >1?
   :added "1.2"}
  ([] 0)
  ([x] x)
  ([x y] (+' x y))
  ([x y & more]
   (reduce1 + (+ x y) more)))

(defn *'
  "Returns the product of nums. (*) returns 1. Supports arbitrary precision.

  print the result. expr's string representation will be produced
  using pr-str in any case."
  [bindings expr iterations & {:keys [print-fn] :or {print-fn 'println}}]
  (let [bs-str   (pr-str bindings)
        expr-str (pr-str expr)]
    `(let ~bindings
       (let [start#   (erlang/monotonic_time.e :nano_seconds)
             ret#     (dotimes [_# ~iterations] ~expr)
             end#     (erlang/monotonic_time.e :nano_seconds)
             elapsed# (/ (- end# start#) 1000000)]
         (~'print-fn (str ~bs-str ", " ~expr-str ", "
                      ~iterations " runs, " elapsed# " msecs"))))))
