Clojure-compat fixes enabling external HTTP-client support (#159)

Generic language fixes so a host-shim library (jolt-lang/http-client) can carry
clj-http-lite without baking any HTTP/native code into core:

- reader: accept #^ (deprecated metadata reader macro) as ^
- (str pattern) returns the raw regex source, not #"..." — pattern composition
  via (re-pattern (str p ...)) now works
- into/conj onto a map merges map items (was (into {} [{:a 1}]) -> {nil nil})
- a Var is callable as its current value (e.g. (wrap #'f) threading a var client)
- core-class reads a :class field off a thrown table, so libraries can throw
  typed exceptions whose (class e) is a JVM class name
- compiled catch unwraps the interpreter's :jolt/exception envelope (__unwrap-ex),
  so a typed throw keeps its class/message across the interpret/compile boundary
- slurp accepts a byte-array; io/copy is generic over :jolt/input-stream /
  :jolt/output-stream stream markers
- instance? gains a registry (__register-instance-check!) for library shim types
- new clojure.test namespace (deftest/is/are/testing/use-fixtures/run-tests with
  class-aware thrown?/thrown-with-msg?)

Spec: test/spec/clojure-interop-fixes-spec.janet.

Co-authored-by: Yogthos <yogthos@gmail.com>
This commit is contained in:
Dmitri Sotnikov 2026-06-17 06:42:52 +00:00 committed by GitHub
parent 951a3000e6
commit 3c853429f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 275 additions and 13 deletions

View file

@ -0,0 +1,29 @@
# Specification: Clojure-compat fixes that landed with HTTP-client support
# (jolt-lang/http-client). All are general language behaviours, exercised here
# across interpret + compile modes by the harness.
(use ../support/harness)
(defspec "interop-fixes / deprecated #^ metadata reader"
["#^ type hint on a param" "\"x\""
"(do (defn f1 [#^String s] s) (f1 \"x\"))"]
["#^\"[B\" array hint" "[1 2]"
"(do (defn f2 [#^\"[B\" b] b) (f2 [1 2]))"]
["#^ is equivalent to ^" "true"
"(= (meta (with-meta [] {:tag (quote String)})) {:tag (quote String)})"])
(defspec "interop-fixes / (str pattern) yields raw source"
["str of a regex" "\"abc\"" "(str #\"abc\")"]
["compose patterns via str" "true"
"(boolean (re-matches (re-pattern (str #\"<\" \"(.*)\" \">\")) \"<hi>\"))"])
(defspec "interop-fixes / into onto a map"
["merges map items" "true" "(= {:a 1 :b 2} (into {} [{:a 1} {:b 2}]))"]
["accepts [k v] pairs" "true" "(= {:a 1} (into {} [[:a 1]]))"]
["map item onto empty {}" "true" "(= {:x 1} (into {} (list {:x 1})))"]
["conj a map onto {}" "true" "(= {:a 1} (conj {} {:a 1}))"])
(defspec "interop-fixes / a var is callable as its value"
["call a var directly" "42"
"(do (def vf (fn [x] (inc x))) ((var vf) 41))"]
["var bound as a client fn" "\"ok\""
"(do (def base (fn [_] \"ok\")) (def mw (fn [client] (fn [req] (client req)))) ((mw (var base)) {}))"])