;; Generic numeric operations work on both int and float (define square (number -> number) (dup *)) ;; Type is preserved through operations (define test-int ( -> int) (5 square)) ; Returns int: 25 (define test-float ( -> float) (2.5 square)) ; Returns float: 6.25 ;; Mixing int and float promotes to float (define mixed ( -> float) (5 2.5 +)) ; int + float → float: 7.5 ;; Generic functions preserve types (define abs (number -> number) (dup 0 < '(neg) '() if)) ;; Works for both: ;; (-5 abs) → 5 (int) ;; (-2.5 abs) → 2.5 (float) ;; You can still be specific when needed (define int-div (int int -> int) (int:/)) ; Integer division (define float-div (float float -> float) (float:/)) ; Floating division ;; But generic / dispatches appropriately ;; (10 3 /) → 3.333... (promotes to float) ;; (10 int:/ 3) → 3 (integer division) ;; Generic square root works on number (define pythag (number number -> number) (dup * swap dup * + sqrt)) ;; (3.0 4.0 pythag) → 5.0 ;; (3 4 pythag) → 5.0 (promoted to float) ;; Polymorphic with number constraint (define double (number -> number) (dup +)) ;; Type-specific when precision matters (define int-average (int int -> int) (+ 2 int:/)) ; Integer average (truncates) (define float-average (float float -> float) (+ 2.0 float:/)) ; Precise average ;; Generic average (define average (number number -> number) (+ 2 /)) ; Promotes to float if needed