#lang racket/base

;; Portable stdlib types — functions that represent universal programming
;; concepts and work across all targets (CLJ, CLJS, JS, Python).
;;
;; Split from stdlib-types.rkt as part of multi-target support.

(require "types.rkt"
         "stdlib-helpers.rkt")

(define STDLIB-PORTABLE
  (hash
   ;; --- collection access (parametric → Any in v0) --------------------------
   'first      (fn-of '(Any) 'Any)
   'second     (fn-of '(Any) 'Any)
   'last       (fn-of '(Any) 'Any)
   'rest       (fn-of '(Any) 'Any)
   'next       (fn-of '(Any) 'Any)
   'nth        (fn-of '(Any Int) 'Any #:rest 'Any)
   'get        (fn-of '(Any Any) 'Any #:rest 'Any)
   'get-in     (fn-of '(Any Any) 'Any #:rest 'Any)
   'count      (fn-of '(Any) 'Int)
   'empty?     (fn-of '(Any) 'Bool)
   'seq        (fn-of '(Any) 'Any)
   'into       (fn-of '(Any Any) 'Any)
   'conj       (fn-of '(Any) 'Any #:rest 'Any)
   'cons       (fn-of '(Any Any) 'Any)
   ;; concat/distinct/sort: parametric over the element type so the typed
   ;; pipeline carries (Vec A) through (the zig backend needs this — it
   ;; can't bind a native loop's element type to Any). concat stays
   ;; variadic; the extra vecs share the element type.
   'concat     (poly-fn '(A) (list (type-app 'Vec (list (tv 'A))))
                        (type-app 'Vec (list (tv 'A)))
                        #:rest (type-app 'Vec (list (tv 'A))))
   'reverse    (fn-of '(Any) 'Any)
   'distinct   (poly-fn '(A) (list (type-app 'Vec (list (tv 'A))))
                        (type-app 'Vec (list (tv 'A))))
   'sort       (poly-fn '(A) (list (type-app 'Vec (list (tv 'A))))
                        (type-app 'Vec (list (tv 'A))))
   'sort-by    (fn-of '(Any Any) 'Any #:rest 'Any)
   'ffirst     (fn-of '(Any) 'Any)
   ;; --- higher-order (polymorphic where useful) -----------------------------
   'map        (poly-fn '(A B)
                 (list (type-fn (list (tv 'A)) #f (tv 'B)))
                 (p 'Any)
                 #:rest (p 'Any))
   'mapv       (poly-fn '(A B)
                 (list (type-fn (list (tv 'A)) #f (tv 'B))
                       (p 'Any))
                 (type-app 'Vec (list (tv 'B))))
   'filter     (poly-fn '(A)
                 (list (type-fn (list (tv 'A)) #f (p 'Any))
                       (p 'Any))
                 (p 'Any))
   'filterv    (poly-fn '(A)
                 (list (type-fn (list (tv 'A)) #f (p 'Any))
                       (p 'Any))
                 (type-app 'Vec (list (tv 'A))))
   'remove     (poly-fn '(A)
                 (list (type-fn (list (tv 'A)) #f (p 'Any))
                       (p 'Any))
                 (p 'Any))
   'mapcat     (fn-of '(Any Any) 'Any #:rest 'Any)
   'reduce     (fn-of '(Any Any) 'Any #:rest 'Any)
   'apply      (fn-of '(Any Any) 'Any #:rest 'Any)
   'comp       (fn-of '() 'Any #:rest 'Any)
   'partial    (fn-of '(Any) 'Any #:rest 'Any)
   ;; --- string ops ---------------------------------------------------------
   'str        (fn-of '() 'String #:rest 'Any)
   'name       (fn-of '(Any) 'String)
   'keyword    (fn-of '(String) 'Keyword)
   'symbol     (fn-of '(String) 'Symbol)
   ;; --- math (variadic on Int; Clojure's are polymorphic, v0 narrows) -----
   ;; Math operators are polymorphic in real Clojure (Long/Double/Ratio).
   ;; v0 types them as variadic Any to avoid spurious type errors on FP work.
   '+          (fn-of '() 'Any #:rest 'Any)
   '-          (fn-of '(Any) 'Any #:rest 'Any)
   '*          (fn-of '() 'Any #:rest 'Any)
   '/          (fn-of '(Any) 'Any #:rest 'Any)
   'mod        (fn-of '(Int Int) 'Int)
   'quot       (fn-of '(Int Int) 'Int)
   'rem        (fn-of '(Int Int) 'Int)
   ;; inc/dec re-adopted (audit row d): cheap Clojure stdlib sugar; no type or
   ;; backend justification for absence. Lowering happens in the per-target
   ;; stdlib emitters (or trivially as (+ x 1) / (- x 1)).
   ;; Params are Number (Clojure's are polymorphic; (inc 2.5) was a false
   ;; positive). The declared Int return is only the fallback for operands
   ;; the numeric-preserving refinement can't classify (Any): the checker
   ;; computes Int/Float/Number from the actual operand types.
   'inc        (fn-of '(Number) 'Int)
   'dec        (fn-of '(Number) 'Int)
   'min        (fn-of '(Number) 'Int #:rest 'Number)
   'max        (fn-of '(Number) 'Int #:rest 'Number)
   'abs        (fn-of '(Number) 'Int)
   'zero?      (fn-of '(Number) 'Bool)
   'pos?       (fn-of '(Number) 'Bool)
   'neg?       (fn-of '(Number) 'Bool)
   'even?      (fn-of '(Int) 'Bool)
   'odd?       (fn-of '(Int) 'Bool)
   ;; --- equality / ordering ------------------------------------------------
   '=          (fn-of '(Any Any) 'Bool)
   ;; not= re-adopted (audit row d): Clojure-canonical negated equality.
   'not=       (fn-of '(Any Any) 'Bool)
   ;; Comparisons accept the numeric tower (Number = (U Int Float)) —
   ;; param-widening only, Bool return unchanged, so no downstream type
   ;; flow changes. (> 2.5 1.0) was a false positive before 2026-06-12.
   '<          (fn-of '(Number Number) 'Bool)
   '>          (fn-of '(Number Number) 'Bool)
   '<=         (fn-of '(Number Number) 'Bool)
   '>=         (fn-of '(Number Number) 'Bool)
   'identical? (fn-of '(Any Any) 'Bool)
   'compare    (fn-of '(Any Any) 'Int)
   'boolean    (fn-of '(Any) 'Bool)
   ;; --- boolean ------------------------------------------------------------
   'not        (fn-of '(Bool) 'Bool)
   'and        (fn-of '() 'Any #:rest 'Any)
   'or         (fn-of '() 'Any #:rest 'Any)
   'true?      (fn-of '(Any) 'Bool)
   'false?     (fn-of '(Any) 'Bool)
   'nil?       (fn-of '(Any) 'Bool)
   'some?      (fn-of '(Any) 'Bool)
   'parse-long   (fn-of '(String) 'Any)
   'parse-double (fn-of '(String) 'Any)
   ;; --- io -----------------------------------------------------------------
   'println    (fn-of '() 'Nil #:rest 'Any)
   'print      (fn-of '() 'Nil #:rest 'Any)
   'pr         (fn-of '() 'Nil #:rest 'Any)
   'pr-str     (fn-of '() 'String #:rest 'Any)
   'newline    (fn-of '() 'Nil)
   'prn        (fn-of '() 'Nil #:rest 'Any)
   ;; --- identity / value ---------------------------------------------------
   'identity   (poly-fn '(A) (list (tv 'A)) (tv 'A))
   'constantly (fn-of '(Any) 'Any)
   ;; --- sequence generators / iteration ------------------------------------
   'range      (fn-of '() 'Any #:rest 'Any)    ; (range), (range n), (range a b), (range a b step)
   'repeat     (fn-of '(Any) 'Any #:rest 'Any) ; (repeat x), (repeat n x)
   'iterate    (fn-of '(Any Any) 'Any)
   'take       (fn-of '(Int Any) 'Any)
   'drop       (fn-of '(Int Any) 'Any)
   'take-while (fn-of '(Any Any) 'Any)
   'drop-while (fn-of '(Any Any) 'Any)
   'partition  (fn-of '(Int Any) 'Any #:rest 'Any)
   'interpose  (fn-of '(Any Any) 'Any)
   ;; --- predicates over collections ----------------------------------------
   'some       (fn-of '(Any Any) 'Any)        ; (some pred coll) — first truthy or nil
   'every?     (fn-of '(Any Any) 'Bool)    ; (every? pred coll)
   ;; --- collection construction --------------------------------------------
   'vec        (fn-of '(Any) 'Any)
   'vector     (fn-of '() 'Any #:rest 'Any)
   'list       (fn-of '() 'Any #:rest 'Any)
   'hash-map   (fn-of '() 'Any #:rest 'Any)
   'sorted-map (fn-of '() 'Any #:rest 'Any)
   'set        (fn-of '(Any) 'Any)
   'hash-set   (fn-of '() 'Any #:rest 'Any)
   ;; --- map / set operations -----------------------------------------------
   'keys       (fn-of '(Any) 'Any)
   'vals       (fn-of '(Any) 'Any)
   'assoc      (fn-of '(Any Any Any) 'Any #:rest 'Any)
   'dissoc     (fn-of '(Any) 'Any #:rest 'Any)
   'update     (fn-of '(Any Any Any) 'Any #:rest 'Any)
   'update-in  (fn-of '(Any Any Any) 'Any #:rest 'Any)
   'merge      (fn-of '() 'Any #:rest 'Any)
   'select-keys (fn-of '(Any Any) 'Any)
   'contains?  (fn-of '(Any Any) 'Bool)
   'find       (fn-of '(Any Any) 'Any)
   'key        (fn-of '(Any) 'Any)
   'val        (fn-of '(Any) 'Any)
   'merge-with (fn-of '(Any) 'Any #:rest 'Any)
   ;; --- string / type predicates -------------------------------------------
   'subs       (fn-of '(String Int) 'String #:rest 'Int)
   'string?    (fn-of '(Any) 'Bool)
   'number?    (fn-of '(Any) 'Bool)
   'integer?   (fn-of '(Any) 'Bool)
   'keyword?   (fn-of '(Any) 'Bool)
   'symbol?    (fn-of '(Any) 'Bool)
   'map?       (fn-of '(Any) 'Bool)
   'vector?    (fn-of '(Any) 'Bool)
   'list?      (fn-of '(Any) 'Bool)
   'set?       (fn-of '(Any) 'Bool)
   'coll?      (fn-of '(Any) 'Bool)
   'sequential? (fn-of '(Any) 'Bool)
   'fn?        (fn-of '(Any) 'Bool)
   ;; --- error / control ----------------------------------------------------
   'ex-info    (fn-of '(String Any) 'Any)
   'ex-data    (fn-of '(Any) 'Any)
   'ex-message (fn-of '(Any) 'String)
   'throw      (fn-of '(Any) 'Any)
   ;; --- atom / ref (universal state management) ----------------------------
   'atom       (fn-of '(Any) 'Any)
   'deref      (fn-of '(Any) 'Any)
   'reset!     (fn-of '(Any Any) 'Any)
   'swap!      (fn-of '(Any Any) 'Any #:rest 'Any)
   'compare-and-set! (fn-of '(Any Any Any) 'Bool)
   'add-watch  (fn-of '(Any Any Any) 'Any)
   'remove-watch (fn-of '(Any Any) 'Any)
   ;; --- array ops (universal) -----------------------------------------------
   'aget       (fn-of '(Any Int) 'Any #:rest 'Int)
   'aset       (fn-of '(Any Int Any) 'Any #:rest 'Any)
   'to-array   (fn-of '(Any) 'Any)
   ;; --- type coercion (universal) -------------------------------------------
   'int        (fn-of '(Any) 'Int)
   'double     (fn-of '(Any) 'Float)
   'char       (fn-of '(Any) 'Any)
   ;; --- collection: more access / manipulation -----------------------------
   'nfirst     (fn-of '(Any) 'Any)
   'nnext      (fn-of '(Any) 'Any)
   'fnext      (fn-of '(Any) 'Any)
   'peek       (fn-of '(Any) 'Any)
   'pop        (fn-of '(Any) 'Any)
   'rand-nth   (fn-of '(Any) 'Any)
   'shuffle    (fn-of '(Any) 'Any)
   'flatten    (fn-of '(Any) 'Any)
   'frequencies (fn-of '(Any) 'Any)
   'group-by   (fn-of '(Any Any) 'Any)
   'zipmap     (fn-of '(Any Any) 'Any)
   'not-empty  (fn-of '(Any) 'Any)
   'butlast    (fn-of '(Any) 'Any)
   'nthrest    (fn-of '(Any Int) 'Any)
   'nthnext    (fn-of '(Any Int) 'Any)
   'subvec     (fn-of '(Any Int) 'Any #:rest 'Int)
   'assoc-in   (fn-of '(Any Any Any) 'Any)
   ;; --- higher-order: more -------------------------------------------------
   'map-indexed (fn-of '(Any Any) 'Any)
   'keep       (fn-of '(Any Any) 'Any)
   'keep-indexed (fn-of '(Any Any) 'Any)
   'run!       (fn-of '(Any Any) 'Nil)
   'juxt       (fn-of '(Any) 'Any #:rest 'Any)
   'complement (fn-of '(Any) 'Any)
   'fnil       (fn-of '(Any) 'Any #:rest 'Any)
   'memoize    (fn-of '(Any) 'Any)
   'trampoline (fn-of '(Any) 'Any #:rest 'Any)
   'reductions (fn-of '(Any Any) 'Any #:rest 'Any)
   ;; --- sequence: more generation / transformation -------------------------
   'cycle      (fn-of '(Any) 'Any)
   'interleave (fn-of '(Any Any) 'Any #:rest 'Any)
   'partition-by (fn-of '(Any Any) 'Any)
   'partition-all (fn-of '(Int Any) 'Any)
   'split-at   (fn-of '(Int Any) 'Any)
   'split-with (fn-of '(Any Any) 'Any)
   'take-last  (fn-of '(Int Any) 'Any)
   'drop-last  (fn-of '(Any) 'Any #:rest 'Any)
   'dedupe     (fn-of '(Any) 'Any)
   'replace    (fn-of '(Any Any) 'Any)
   'repeatedly (fn-of '(Any) 'Any #:rest 'Any)
   ;; --- transducers --------------------------------------------------------
   'transduce  (fn-of '(Any Any Any Any) 'Any)
   'sequence   (fn-of '(Any Any) 'Any)
   'eduction   (fn-of '() 'Any #:rest 'Any)
   'completing (fn-of '(Any) 'Any #:rest 'Any)
   'halt-when  (fn-of '(Any) 'Any #:rest 'Any)
   'cat        (fn-of '(Any) 'Any)
   ;; --- map / set: more operations -----------------------------------------
   'rename-keys (fn-of '(Any Any) 'Any)
   'map-keys   (fn-of '(Any Any) 'Any)
   'map-vals   (fn-of '(Any Any) 'Any)
   ;; --- regex / matching ---------------------------------------------------
   're-pattern (fn-of '(String) 'Any)
   're-matches (fn-of '(Any String) 'Any)
   're-find    (fn-of '(Any) 'Any #:rest 'Any)
   're-seq     (fn-of '(Any String) 'Any)
   're-groups  (fn-of '(Any) 'Any)
   ;; --- namespace / var inspection (portable subset) -----------------------
   'namespace  (fn-of '(Any) 'Any)
   'meta       (fn-of '(Any) 'Any)
   'with-meta  (fn-of '(Any Any) 'Any)
   'vary-meta  (fn-of '(Any Any) 'Any #:rest 'Any)
   ;; --- misc core ----------------------------------------------------------
   'rand       (fn-of '() 'Float #:rest 'Any)
   'rand-int   (fn-of '(Int) 'Int)
   'gensym     (fn-of '() 'Symbol #:rest 'Any)
   'hash       (fn-of '(Any) 'Int)
   'max-key    (fn-of '(Any Any) 'Any #:rest 'Any)
   'min-key    (fn-of '(Any Any) 'Any #:rest 'Any)
   'not-any?   (fn-of '(Any Any) 'Bool)
   'not-every? (fn-of '(Any Any) 'Bool)
   'bounded-count (fn-of '(Int Any) 'Int)
   'tagged-literal (fn-of '(Symbol Any) 'Any)
   'tagged-literal? (fn-of '(Any) 'Bool)
   'inst-ms    (fn-of '(Any) 'Int)
   'uuid       (fn-of '(String) 'Any)
   'random-uuid (fn-of '() 'Any)
   'parse-uuid (fn-of '(String) 'Any)
   'parse-boolean (fn-of '(String) 'Any)
   ;; --- printing / formatting ----------------------------------------------
   'with-out-str (fn-of '() 'String #:rest 'Any)
   'print-str  (fn-of '() 'String #:rest 'Any)
   'println-str (fn-of '() 'String #:rest 'Any)
   'printf     (fn-of '(String) 'Nil #:rest 'Any)
   ;; --- string: more (unqualified only) ------------------------------------
   'format     (fn-of '(String) 'String #:rest 'Any)

   ;; =========================================================================
   ;; AUTO-GENERATED portable entries
   ;; =========================================================================
   '==             (fn-of '(Any Any) 'Any #:rest 'Any)
   'any?           (fn-of '(Any) 'Bool)
   'array-map      (fn-of '() 'Any #:rest 'Any)
   'bit-and        (fn-of '(Int Int) 'Int #:rest 'Int)
   'bit-and-not    (fn-of '(Int Int) 'Int #:rest 'Int)
   'bit-clear      (fn-of '(Int Int) 'Int)
   'bit-flip       (fn-of '(Int Int) 'Int)
   'bit-not        (fn-of '(Int) 'Int)
   'bit-or         (fn-of '(Int Int) 'Int #:rest 'Int)
   'bit-set        (fn-of '(Int Int) 'Int)
   'bit-shift-left (fn-of '(Int Int) 'Int)
   'bit-shift-right (fn-of '(Int Int) 'Int)
   'bit-test       (fn-of '(Int Int) 'Bool)
   'bit-xor        (fn-of '(Int Int) 'Int #:rest 'Int)
   'boolean?       (fn-of '(Any) 'Bool)
   'comparator     (fn-of '(Any) 'Any)
   'denominator    (fn-of '(Any) 'Int)
   'disj           (fn-of '(Any Any) 'Any #:rest 'Any)
   'distinct?      (fn-of '(Any Any) 'Bool #:rest 'Any)
   'doall          (fn-of '(Any) 'Any #:rest 'Any)
   'dorun          (fn-of '(Any) 'Any #:rest 'Any)
   'empty          (fn-of '(Any) 'Any)
   'ensure-reduced (fn-of '(Any) 'Any)
   'every-pred     (fn-of '(Any Any Any) 'Any #:rest 'Any)
   'ex-cause       (fn-of '(Any) 'Any)
   'flush          (fn-of '() 'Nil)
   'infinite?      (fn-of '(Any) 'Bool)
   'iteration      (fn-of '(Any) 'Any #:rest 'Any)
   'list*          (fn-of '(Any Any Any Any) 'Any #:rest 'Any)
   'map-entry?     (fn-of '(Any) 'Bool)
   'numerator      (fn-of '(Any) 'Int)
   'partitionv     (fn-of '(Any Any) 'Any #:rest 'Any)
   'prn-str        (fn-of '() 'String #:rest 'Any)
   'random-sample  (fn-of '(Any) 'Any #:rest 'Any)
   'read-line      (fn-of '() 'String)
   'reduce-kv      (fn-of '(Any Any Any) 'Any)
   'reduced        (fn-of '(Any) 'Any)
   'reduced?       (fn-of '(Any) 'Bool)
   'replicate      (fn-of '(Any Any) 'Any)
   'rseq           (fn-of '(Any) 'Any)
   'rsubseq        (fn-of '(Any Any Any) 'Any #:rest 'Any)
   'seq?           (fn-of '(Any) 'Bool)
   'some-fn        (fn-of '(Any Any Any) 'Any #:rest 'Any)
   'sorted-map-by  (fn-of '(Any) 'Any #:rest 'Any)
   'sorted-set     (fn-of '() 'Any #:rest 'Any)
   'sorted-set-by  (fn-of '(Any) 'Any #:rest 'Any)
   'splitv-at      (fn-of '(Any Any) 'Any)
   'subseq         (fn-of '(Any Any Any) 'Any #:rest 'Any)
   'take-nth       (fn-of '(Any) 'Any #:rest 'Any)
   'tree-seq       (fn-of '(Any Any Any) 'Any)
   'unreduced      (fn-of '(Any) 'Any)
   'unsigned-bit-shift-right (fn-of '(Int Int) 'Int)
   'update-keys    (fn-of '(Any Any) 'Any)
   'update-vals    (fn-of '(Any Any) 'Any)
   ))

(provide STDLIB-PORTABLE)
