Skip to content

Commit 96a3ffb

Browse files
committed
unify types for quotient, remainder and quotient/remainder
use the same spec to generate types for them. closes #1039
1 parent adcc138 commit 96a3ffb

File tree

2 files changed

+65
-63
lines changed

2 files changed

+65
-63
lines changed

typed-racket-lib/typed-racket/base-env/base-env-numeric.rkt

Lines changed: 54 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,55 @@
682682
((Un -PosReal -NegReal) . -> . -PosReal)
683683
(-Real . -> . -NonNegReal)))
684684

685+
686+
(define-syntax (quotient-reminder-cases stx)
687+
(syntax-parse stx #:datum-literals (->)
688+
[(_ (-> a b (c d)) ...)
689+
#'(values (list (-> a b c) ...)
690+
(list (-> a b d) ...)
691+
(list (-> a b (-values (list c d))) ...))]))
692+
693+
(define-values (quotient-spec remainder-spec quotient/remainder-spec)
694+
(quotient-reminder-cases
695+
(-Zero -Int . -> . (-Zero -Zero))
696+
(-One -One . -> . (-Zero -One))
697+
;; division by one is identity, and has no remainder
698+
(-PosByte -One . -> . (-PosByte -Zero))
699+
(-Byte -One . -> . (-Byte -Zero))
700+
(-PosIndex -One . -> . (-PosIndex -Zero))
701+
(-Index -One . -> . (-Index -Zero))
702+
(-PosFixnum -One . -> . (-PosFixnum -Zero))
703+
(-NonNegFixnum -One . -> . (-NonNegFixnum -Zero))
704+
(-NegFixnum -One . -> . (-NegFixnum -Zero))
705+
(-NonPosFixnum -One . -> . (-NonPosFixnum -Zero))
706+
(-Fixnum -One . -> . (-Fixnum -Zero))
707+
(-Byte -Nat . -> . (-Byte -Byte))
708+
(-Byte -Int . -> . (-Fixnum -Byte))
709+
(-Index -Nat . -> . (-Index -Index))
710+
(-Index -Int . -> . (-Fixnum -Index))
711+
(-NonNegFixnum -Byte . -> . (-NonNegFixnum -Byte))
712+
(-NonNegFixnum -NonNegFixnum . -> . (-NonNegFixnum -NonNegFixnum))
713+
(-NonNegFixnum -NonPosFixnum . -> . (-NonPosFixnum -NonNegFixnum))
714+
(-NonPosFixnum -NonNegFixnum . -> . (-NonPosFixnum -NonPosFixnum))
715+
(-NonPosFixnum -NonPosFixnum . -> . (-Nat -NonPosFixnum))
716+
(-NonNegFixnum -Nat . -> . (-NonNegFixnum -NonNegFixnum))
717+
(-NonNegFixnum -Int . -> . (-Fixnum -NonNegFixnum))
718+
(-Nat -Byte . -> . (-Nat -Byte))
719+
(-Nat -Index . -> . (-Nat -Index))
720+
(-Nat -NonNegFixnum . -> . (-Nat -NonNegFixnum))
721+
;; in the following cases, we can't guarantee that the quotient is within
722+
;; fixnum range: (quotient min-fixnum -1) -> max-fixnum + 1
723+
(-NonPosFixnum -Int . -> . (-Int -NonPosFixnum))
724+
(-Fixnum -Int . -> . (-Int -Fixnum))
725+
(-Int -Fixnum . -> . (-Int -Fixnum))
726+
(-Nat -Nat . -> . (-Nat -Nat))
727+
(-Nat -NonPosInt . -> . (-NonPosInt -Nat))
728+
(-Nat -Int . -> . (-Int -Nat))
729+
(-NonPosInt -Nat . -> . (-NonPosInt -NonPosInt))
730+
(-NonPosInt -NonPosInt . -> . (-Nat -NonPosInt))
731+
(-NonPosInt -Int . -> . (-Int -NonPosInt))
732+
(-Int -Int . -> . (-Int -Int))))
733+
685734
;Check to ensure we fail fast if the flonum bindings change
686735
(define-namespace-anchor anchor)
687736
(let ((flonum-ops #'([unsafe-flround flround]
@@ -1309,36 +1358,10 @@
13091358
(-> -NonPosReal -NegReal)
13101359
(map unop (list -Real -FloatComplex -SingleFlonumComplex -InexactComplex N)))]
13111360

1312-
[quotient
1313-
(from-cases
1314-
(-Zero -Int . -> . -Zero)
1315-
(map (lambda (t) (-> t -One t)) ; division by one is identity
1316-
(list -PosByte -Byte -PosIndex -Index
1317-
-PosFixnum -NonNegFixnum -NegFixnum -NonPosFixnum -Fixnum))
1318-
(-Byte -Nat . -> . -Byte)
1319-
(-Byte -Int . -> . -Fixnum) ; may be negative
1320-
(-Index -Nat . -> . -Index)
1321-
(-Index -Int . -> . -Fixnum) ; same.
1322-
;; we don't have equivalent for fixnums:
1323-
;; (quotient min-fixnum -1) -> max-fixnum + 1
1324-
(commutative-binop -NonNegFixnum -NonPosFixnum -NonPosFixnum)
1325-
(-NonPosFixnum -NonPosFixnum . -> . -Nat)
1326-
(-NonNegFixnum -Nat . -> . -NonNegFixnum)
1327-
(-NonNegFixnum -Int . -> . -Fixnum)
1328-
(binop -Nat)
1329-
(commutative-binop -Nat -NonPosInt -NonPosInt)
1330-
(-NonPosInt -NonPosInt . -> . -Nat)
1331-
(binop -Int))]
1332-
[remainder ; result has same sign as first arg
1333-
(from-cases
1334-
(-One -One . -> . -Zero)
1335-
(map (lambda (t) (list (-> -Nat t t)
1336-
(-> t -Int t)))
1337-
(list -Byte -Index -NonNegFixnum -Nat))
1338-
(-NonPosFixnum -Int . -> . -NonPosFixnum)
1339-
(-NonPosInt -Int . -> . -NonPosInt)
1340-
(commutative-binop -Fixnum -Int)
1341-
(binop -Int))]
1361+
[quotient (from-cases quotient-spec)]
1362+
1363+
[remainder (from-cases remainder-spec)]; result has same sign as first arg
1364+
13421365
[modulo ; result has same sign as second arg
13431366
(from-cases
13441367
(-One -One . -> . -Zero)
@@ -1350,39 +1373,7 @@
13501373
(commutative-binop -Fixnum -Int)
13511374
(binop -Int))]
13521375
;; should be consistent with quotient and remainder
1353-
[quotient/remainder
1354-
(from-cases
1355-
(-Zero -Int . -> . (-values (list -Zero -Zero)))
1356-
(-One -One . -> . (-values (list -Zero -One)))
1357-
;; division by one is identity, and has no remainder
1358-
(map (lambda (t) (t -One . -> . (-values (list t -Zero))))
1359-
(list -PosByte -Byte -PosIndex -Index
1360-
-PosFixnum -NonNegFixnum -NegFixnum -NonPosFixnum -Fixnum))
1361-
(-Byte -Nat . -> . (-values (list -Byte -Byte)))
1362-
(-Byte -Int . -> . (-values (list -Fixnum -Byte)))
1363-
(-Index -Nat . -> . (-values (list -Index -Index)))
1364-
(-Index -Int . -> . (-values (list -Fixnum -Index)))
1365-
(-Nat -Byte . -> . (-values (list -Nat -Byte)))
1366-
(-Nat -Index . -> . (-values (list -Nat -Index)))
1367-
(-NonNegFixnum -NonNegFixnum . -> . (-values (list -NonNegFixnum -NonNegFixnum)))
1368-
(-NonNegFixnum -NonPosFixnum . -> . (-values (list -NonPosFixnum -NonNegFixnum)))
1369-
(-NonPosFixnum -NonNegFixnum . -> . (-values (list -NonPosFixnum -NonPosFixnum)))
1370-
(-NonPosFixnum -NonPosFixnum . -> . (-values (list -NonNegFixnum -NonPosFixnum)))
1371-
(-NonNegFixnum -Nat . -> . (-values (list -NonNegFixnum -NonNegFixnum)))
1372-
(-NonNegFixnum -Int . -> . (-values (list -Fixnum -NonNegFixnum)))
1373-
(-Nat -NonNegFixnum . -> . (-values (list -Nat -NonNegFixnum)))
1374-
;; in the following cases, we can't guarantee that the quotient is within
1375-
;; fixnum range: (quotient min-fixnum -1) -> max-fixnum + 1
1376-
(-NonPosFixnum -Int . -> . (-values (list -Int -NonPosFixnum)))
1377-
(-Fixnum -Int . -> . (-values (list -Int -Fixnum)))
1378-
(-Int -Fixnum . -> . (-values (list -Int -Fixnum)))
1379-
(-Nat -Nat . -> . (-values (list -Nat -Nat)))
1380-
(-Nat -NonPosInt . -> . (-values (list -NonPosInt -Nat)))
1381-
(-Nat -Int . -> . (-values (list -Int -Nat)))
1382-
(-NonPosInt -Nat . -> . (-values (list -NonPosInt -NonPosInt)))
1383-
(-NonPosInt -NonPosInt . -> . (-values (list -Nat -NonPosInt)))
1384-
(-NonPosInt -Int . -> . (-values (list -Int -NonPosInt)))
1385-
(-Int -Int . -> . (-values (list -Int -Int))))]
1376+
[quotient/remainder (from-cases quotient/remainder-spec)]
13861377

13871378
[arithmetic-shift (cl->* (-Zero -NonPosInt . -> . -Zero)
13881379
(-Byte -NonPosInt . -> . -Byte)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#lang typed/racket/base
2+
3+
(: my-remainder1 (-> Integer Fixnum Fixnum))
4+
(define (my-remainder1 x y)
5+
(define-values [q r]
6+
(quotient/remainder x y))
7+
r)
8+
9+
(: my-remainder2 (-> Integer Fixnum Fixnum))
10+
(define (my-remainder2 x y)
11+
(remainder x y))

0 commit comments

Comments
 (0)