clojure.string toString coercion; some-fn/ifn? reference semantics; misc host gaps
The clojure.string case fns and searches now take any Object s through its toString like the reference's ^CharSequence signatures ((upper-case :kw) is ":KW", (capitalize 1) is "1"); nil throws, and a nil substr in starts-with?/ends-with? throws. some-fn re-ported with the reference arities: (some-fn) is an arity error and a no-match result is the last predicate's own falsy value (false, not nil). ifn? covers multimethods, promises (which are now invocable — calling one delivers, via a cold-path invoke-arm registry that costs the hot dispatch nothing), and deftypes implementing IFn's invoke. One structural find on the way: defmulti/defmethod deferred inside a fn body (the deftest pattern) interned/resolved in whatever namespace was current when they RAN, not the one they were written in — the macros now bake their expansion ns and the setups honor it. Also: Boolean/Integer/Double wrapper ctors, primitive TYPE statics (Integer/TYPE etc.), .reduce on collections (IReduce), and Long/TYPE. cts baseline 5857 -> 5904 pass, 58 -> 28 errors, 57 baselined namespaces — the string cluster, some-fn, ifn-qmark, boolean-qmark, and reduce namespaces are all fully clean. 7 JVM-certified corpus rows; spec entry.
This commit is contained in:
parent
a9542077fc
commit
e17bcfd0af
15 changed files with 1100 additions and 941 deletions
|
|
@ -61,26 +61,36 @@
|
|||
|
||||
(define (jolt-defmulti-setup name-sym dispatch . opts)
|
||||
(let-values (((dk h) (parse-mm-opts opts)))
|
||||
(let ((mf (make-jolt-multifn (symbol-t-name name-sym) dispatch
|
||||
(new-mm-table) dk h (new-mm-table))))
|
||||
(def-var! (chez-current-ns) (symbol-t-name name-sym) mf)
|
||||
(let* ((sns (symbol-t-ns name-sym))
|
||||
;; the macro qualifies the name with its EXPANSION ns, so a defmulti
|
||||
;; deferred inside a fn (a deftest body) still defines in the ns it
|
||||
;; was written in, not whatever ns is current when it finally runs.
|
||||
(ns (if (string? sns) sns (chez-current-ns)))
|
||||
(mf (make-jolt-multifn (symbol-t-name name-sym) dispatch
|
||||
(new-mm-table) dk h (new-mm-table))))
|
||||
(def-var! ns (symbol-t-name name-sym) mf)
|
||||
mf)))
|
||||
|
||||
;; (defmethod-setup 'mm dispatch-val impl) — add a method. Auto-creates the multifn
|
||||
;; if absent (defmethod before defmulti — rare; identity dispatch as a fallback).
|
||||
(define (jolt-defmethod-setup mm-sym dval impl)
|
||||
(define (jolt-defmethod-setup mm-sym dval impl . rest)
|
||||
(let* ((nm (symbol-t-name mm-sym))
|
||||
(sns (symbol-t-ns mm-sym))
|
||||
(qns (and sns (not (jolt-nil? sns)) (not (null? sns)) sns))
|
||||
;; the macro passes its EXPANSION ns so a defmethod deferred inside a
|
||||
;; fn resolves like the JVM (against the ns it was written in, not the
|
||||
;; ns current when it runs); absent (old emitted code) fall back to the
|
||||
;; runtime ns.
|
||||
(here (if (and (pair? rest) (string? (car rest))) (car rest) (chez-current-ns)))
|
||||
;; qualified (cf.mm/ext) resolves in its own ns (cross-ns defmethod);
|
||||
;; unqualified resolves in the current ns, else a :refer's home ns (so a
|
||||
;; unqualified resolves in the writing ns, else a :refer's home ns (so a
|
||||
;; defmethod on a referred multifn lands on the real one), else stays in
|
||||
;; the current ns (a shadow, as before).
|
||||
;; the writing ns (a shadow, as before).
|
||||
(mns (cond
|
||||
(qns (or (chez-resolve-alias (chez-current-ns) qns) qns))
|
||||
((var-cell-lookup (chez-current-ns) nm) (chez-current-ns))
|
||||
((chez-resolve-refer (chez-current-ns) nm) => values)
|
||||
(else (chez-current-ns))))
|
||||
(qns (or (chez-resolve-alias here qns) qns))
|
||||
((var-cell-lookup here nm) here)
|
||||
((chez-resolve-refer here nm) => values)
|
||||
(else here)))
|
||||
(cur (var-deref mns nm))
|
||||
(mf (if (jolt-multifn? cur) cur
|
||||
;; auto-create: copy the dispatch fn + default from a same-named
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue