WP: don't let a recursive pass-through poison a param to :any (#233)
The whole-program fixpoint collects a self-recursive call's arg types into the fn's own params. When a recursive call threads a param straight through unchanged (same arg, same position — e.g. ray-cast passing `hittables` to itself), that arg's type is the param's own current type: :any until external callers determine it. And :any is absorbing, so collecting it pinned the param at :any forever — the type a caller supplied (a vector of records) was lost, and the fn's field reads stayed generic. Skip a same-position pass-through arg in the self-recursion collection (contribute the join identity). It can't add information — param i ⊇ param i is trivial — so dropping it is sound; the param is still constrained by every external caller and by any non-pass-through recursive arg. Applies to both self-recursion paths: a `defn` recursing through its var, and a named fn literal recursing via its self-local. This is why ray-cast's `ray` typed (its recursion passes a fresh ray) but `hittables` didn't (passed through). With the fix, hittables keeps its vec<Sphere> element type, so hit-all's reduce element — and hit-sphere's reads — type without any hint: ray tracer 38.4s -> 31.3s (~1.23x) with no annotations. run-wp.ss: a recursive fn threading a vec param through keeps its element type. make test / shakesmoke green, selfhost holds, 0 new divergences. Co-authored-by: Yogthos <yogthos@gmail.com>
This commit is contained in:
parent
09345f10c2
commit
8c9cba44b3
3 changed files with 307 additions and 265 deletions
|
|
@ -91,6 +91,18 @@
|
|||
(check "self-recursive same-type param keeps its seed"
|
||||
(jolt-truthy? (param-seeds-for "user/grow")) #t)
|
||||
|
||||
;; a recursive fn that threads a param STRAIGHT THROUGH its recursion (same arg at
|
||||
;; the same position) must keep that param's type — a pass-through self-call adds no
|
||||
;; information and must not poison the param to :any. This is the ray tracer's
|
||||
;; hittables, passed unchanged through ray-cast's recursion while its reduce element
|
||||
;; reads the records' fields.
|
||||
(define cwalk (anode "(def cwalk (fn [hs] (reduce (fn [acc h] (:left h)) nil hs)))"))
|
||||
(define crec (anode "(def crec (fn [hs d] (if (< d 0) nil (do (cwalk hs) (crec hs (- d 1))))))"))
|
||||
(define cdrv (anode "(def cdrive (fn [] (crec [(->Node nil nil) (->Node nil nil)] 5)))"))
|
||||
(wp-infer! (jolt-vector cwalk crec cdrv))
|
||||
(check "recursion pass-through param keeps its vec element type"
|
||||
(contains-sub? (pr-str (param-seeds-for "user/crec")) "user.Node") #t)
|
||||
|
||||
(if (= fails 0)
|
||||
(begin (printf "wp gate: ~a/~a passed\n" total total) (exit 0))
|
||||
(begin (printf "wp gate: ~a/~a passed (~a failed)\n" (- total fails) total fails) (exit 1)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue