Skip to content

Commit d32218a

Browse files
author
Andrew Kent
authored
have inst use Any as default type for omitted args
In addition to potentially being convenient, this helps us not break backwards compatibility when APIs add features that require additional type variables to properly type.
1 parent 4a869d9 commit d32218a

File tree

5 files changed

+35
-16
lines changed

5 files changed

+35
-16
lines changed

typed-racket-doc/typed-racket/scribblings/reference/special-forms.scrbl

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -555,14 +555,25 @@ protect higher-order uses of the value.
555555
Instantiate the type of @racket[e] with types @racket[t ...] or with the
556556
poly-dotted types @racket[t ... t ooo bound]. @racket[e] must
557557
have a polymorphic type that can be applied to the supplied number of type
558-
variables. This is legal only in expression contexts.
558+
variables. For non-poly-dotted functions, however, fewer arguments can be
559+
provided and the omitted types default to @racket[Any].
560+
@racket[inst] is legal only in expression contexts.
559561
@ex[(foldl (inst cons Integer Integer) null (list 1 2 3 4))
560562

561-
(: fold-list : (All (A) (Listof A) -> (Listof A)))
562-
(define (fold-list lst)
563-
(foldl (inst cons A A) null lst))
563+
(: my-cons (All (A B) (-> A B (Pairof A B))))
564+
(define my-cons cons)
564565

565-
(fold-list (list "1" "2" "3" "4"))
566+
(: foldl-list : (All (α) (Listof α) -> (Listof α)))
567+
(define (foldl-list lst)
568+
(foldl (inst my-cons α (Listof α)) null lst))
569+
570+
(foldl-list (list "1" "2" "3" "4"))
571+
572+
(: foldr-list : (All (α) (Listof α) -> Any))
573+
(define (foldr-list lst)
574+
(foldr (inst my-cons α) null lst))
575+
576+
(foldr-list (list "1" "2" "3" "4"))
566577

567578
(: my-values : (All (A B ...) (A B ... -> (values A B ... B))))
568579
(define (my-values arg . args)
@@ -683,7 +694,8 @@ a @racket[require/typed] form. Here is an example of using
683694
so we need to use @racket[case->].
684695

685696
@history[#:changed "1.4" @elem{Added the @racket[#:type-name] option.}
686-
#:changed "1.6" "Added syntax for struct type variables, only works in unsafe requires"]}
697+
#:changed "1.6" "Added syntax for struct type variables, only works in unsafe requires."
698+
#:changed "1.12" @elem{Added default type @racket[Any] for omitted @racket[inst] args.}]}
687699

688700
@defform[(require/typed/provide m rt-clause ...)]{
689701
Similar to @racket[require/typed], but also provides the imported identifiers.

typed-racket-lib/typed-racket/typecheck/tc-expression.rkt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,12 @@
7777
(tc-error/expr #:return -Bottom "Cannot instantiate non-polymorphic type ~a"
7878
(cleanup-type ty))]
7979
[(and (Poly? ty)
80-
(not (= (syntax-length inst) (Poly-n ty))))
80+
(> (syntax-length inst) (Poly-n ty)))
8181
(tc-error/expr #:return -Bottom
82-
"Wrong number of type arguments to polymorphic type ~a:\nexpected: ~a\ngot: ~a"
82+
"Too many type arguments to polymorphic type ~a:\nexpected ~a or fewer\ngot: ~a"
8383
(cleanup-type ty) (Poly-n ty) (syntax-length inst))]
84-
[(and (PolyDots? ty) (not (>= (syntax-length inst) (sub1 (PolyDots-n ty)))))
84+
[(and (PolyDots? ty)
85+
(not (>= (syntax-length inst) (sub1 (PolyDots-n ty)))))
8586
;; we can provide 0 arguments for the ... var
8687
(tc-error/expr #:return -Bottom
8788
"Wrong number of type arguments to polymorphic type ~a:\nexpected at least: ~a\ngot: ~a"

typed-racket-lib/typed-racket/types/utils.rkt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
(define (instantiate-poly t types)
1818
(match t
1919
[(Poly: ns body)
20-
(unless (= (length types) (length ns))
20+
(unless (<= (length types) (length ns))
2121
(int-err "instantiate-poly: wrong number of types: expected ~a, got ~a"
2222
(length ns) (length types)))
23-
(subst-all (make-simple-substitution ns types) body)]
23+
;; use Any as the default type for any omitted types
24+
(subst-all (make-simple-substitution ns (list-extend ns types Univ))
25+
body)]
2426
[(PolyDots: (list fixed ... dotted) body)
2527
(unless (>= (length types) (length fixed))
2628
(int-err

typed-racket-lib/typed-racket/utils/utils.rkt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,11 @@ at least theoretically.
246246
;; Listof[A] Listof[B] B -> Listof[B]
247247
;; pads out t to be as long as s
248248
(define (list-extend s t extra)
249-
(append t (build-list (max 0 (- (length s) (length t))) (lambda _ extra))))
249+
(define s-len (length s))
250+
(define t-len (length t))
251+
(cond
252+
[(<= s-len t-len) t]
253+
[else (append t (build-list (- s-len t-len) (λ _ extra)))]))
250254

251255
;; does l1 end with l2?
252256
;; e.g. (list 1 2 3) ends with (list 2 3)

typed-racket-test/unit-tests/typecheck-tests.rkt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,10 +1440,10 @@
14401440
[tc-e (remf* symbol? '(a b c)) (-lst (one-of/c 'a 'b 'c))]
14411441
[tc-e (check-duplicates '("a" "a" "b")) (-opt -String)]
14421442
[tc-e (check-duplicates '("a" "a" "b") string=?) (-opt -String)]
1443-
;[tc-e ((inst check-duplicates String Number)
1444-
; '("a" "aa" "aaa")
1445-
; #:key string-length)
1446-
; (-opt -String)]
1443+
[tc-e ((inst check-duplicates String Number)
1444+
'("a" "aa" "aaa")
1445+
#:key string-length)
1446+
(-opt -String)]
14471447
[tc-e ((inst check-duplicates String Any 'nope)
14481448
'("a" "a" "b")
14491449
string=?

0 commit comments

Comments
 (0)