type-expander-test.rkt (26837B)
1 #lang typed/racket 2 3 (require type-expander 4 typed/rackunit 5 (for-syntax type-expander/expander 6 racket/list 7 version/utils 8 rackunit 9 syntax/parse)) 10 11 ; Tests for expand-type 12 (begin 13 ;; Test harness: 14 (begin 15 (define-syntax (test-expander stx) 16 (syntax-parse stx 17 [(_ type expanded-type) 18 (let ([actual (syntax->datum (expand-type #'type))] 19 [expected (syntax->datum #'expanded-type)]) 20 (unless (equal? actual expected) 21 (raise-syntax-error 22 'test-expander 23 (format "test-expander failed: expected ~a, got ~a" 24 expected 25 actual) 26 stx 27 #'type)) 28 #`(check-equal? '#,actual 29 '#,expected))]))) 30 31 ; Simple identity expander test, with a different case when used as a 32 ; simple identifier. 33 34 (begin 35 (define-type-expander (id stx) 36 (syntax-case stx () 37 [(_ t) #'t] 38 [x #'(∀ (A) (→ A A))])) 39 40 (test-expander (id Number) Number) 41 (test-expander id (∀ (A) (→ A A)))) 42 43 (begin 44 (define-type-expander (double stx) 45 (syntax-case stx () 46 [(_ t) #'(id (Pairof (id t) t))])) 47 48 (test-expander (∀ (A) (→ A (id (double (id A))))) 49 (∀ (A) (→ A (Pairof A A)))) 50 51 (test-expander (→ Any Boolean : (double (id A))) 52 (→ Any Boolean : (Pairof A A)))) 53 54 ;; Curry expander arguments: 55 (begin 56 (define-type-expander (CPairof stx) 57 (syntax-case stx () 58 [(_ a) #'(curry Pairof a)] 59 [(_ a b) #'(Pairof a b)])) 60 61 (test-expander (CPairof Number String) 62 (Pairof Number String)) 63 64 (test-expander ((CPairof Number) String) 65 (Pairof Number String)) 66 67 (check-equal? (ann (ann '(1 . "b") (CPairof Number String)) 68 (Pairof Number String)) 69 '(1 . "b")) 70 71 (check-equal? (ann (ann '(1 . "c") ((CPairof Number) String)) 72 (Pairof Number String)) 73 '(1 . "c"))) 74 75 ;; Shadowing with ∀ variables: 76 (begin 77 (test-expander (∀ (id) (→ id)) 78 (∀ (id) (→ id))) 79 (test-expander (∀ (id2) (→ id)) 80 (∀ (id2) (→ (∀ (A) (→ A A)))))) 81 82 (begin 83 (define-type-expander (Repeat stx) 84 (syntax-case stx () 85 [(_ t n) #`(List #,@(map (λ (x) #'t) 86 (range (syntax->datum #'n))))])) 87 88 (test-expander (Repeat Number 5) 89 (List Number Number Number Number Number))) 90 91 (begin 92 (: count-five-more (→ Number (Repeat Number 5))) 93 (define (count-five-more x) 94 (list (+ x 1) (+ x 2) (+ x 3) (+ x 4) (+ x 5))) 95 96 (check-equal? (count-five-more 3) 97 '(4 5 6 7 8)) 98 (check-equal? (ann (count-five-more 15) (Repeat Number 5)) 99 '(16 17 18 19 20))) 100 101 ;; Shadowing with Rec variables: 102 103 (begin 104 (: repeat-shadow (→ Number (Rec Repeat (U Null (List Number Repeat))))) 105 (define (repeat-shadow n) 106 (if (= n 0) 107 '() 108 (list n (repeat-shadow (sub1 n))))) 109 (check-equal? (repeat-shadow 5) 110 '(5 (4 (3 (2 (1 ())))))) 111 (test-expander (→ Number (Rec Repeat (U Null (List Number Repeat)))) 112 (→ Number (Rec Repeat (U Null (List Number Repeat)))))) 113 114 ;; Shadowing with Let: 115 116 (begin 117 (let () 118 (define-type-expander (exp stx) 119 #'(List 1 2 3)) 120 121 (define-type e String) 122 (: x (List e (Let ([e exp]) e))) 123 (define x (list "e1" (list 1 2 3))) 124 (check-equal? x '("e1" (1 2 3))) 125 (test-expander (List e (Let ([e exp]) e)) 126 (List e (List 1 2 3))) 127 128 (: y (List e)) 129 (define y (list "e2")) 130 (check-equal? y '("e2")) 131 (test-expander (List e) 132 (List e)) 133 (void))) 134 135 ;; Let, Λ and ∀ 136 (begin 137 (let () 138 (define-type-expander Str1 (λ (_) #'String)) 139 140 (test-expander (Let ([Number Str1]) Number) 141 String) 142 (test-expander (Let ([Number (Λ stx #'String)]) (Number)) 143 String) 144 (test-expander (Let ([Number (Λ stx #'Str1)]) (Number)) 145 String) 146 (test-expander (Let ([Number (Λ stx #'String)]) Number) 147 String) 148 149 (test-expander ((∀ (A) (Pairof A A)) Number) 150 (Pairof Number Number)) 151 (test-expander (Let ([String (∀ (A) (Pairof A A))]) 152 (String Number)) 153 (Pairof Number Number)) 154 155 (test-expander (Let ([Poly-Repeat 156 (Λ (_ n) 157 #`(∀ (A) 158 (List #,@(map (λ (_) #'A) 159 (range (syntax-e #'n))))))] 160 [Number String]) 161 ((Poly-Repeat 5) Number)) 162 (List String String String String String)) 163 164 (test-expander (Let ([Poly-Repeat 165 (Λ (_ n) 166 #`(∀ (A) 167 (List #,@(map (λ (_) #'A) 168 ;; like above, but also works 169 ;; without the syntax-e here: 170 (range n)))))] 171 [Number String]) 172 ((Poly-Repeat 5) Number)) 173 (List String String String String String)) 174 175 (ann '(1 . "b") ((Let ([Foo String]) 176 (∀ (ty) 177 (Pairof ty Foo))) 178 Integer)) 179 180 (test-expander ((∀ (A1) 181 (Let () 182 (Let () 183 (Let () 184 (Let () 185 A1))))) 186 Number) 187 Number) 188 189 (void))) 190 191 ;; Let*, Letrec 192 (let () 193 (test-expander 194 (Letrec ([Poly-Repeat 195 (Λ (_ n) 196 (if (= 0 n) 197 #'(∀ (A) Null) 198 #`(∀ (A) 199 (Pairof A 200 ((Poly-Repeat #,(sub1 n)) A)))))] 201 [Number String]) 202 ((Poly-Repeat 5) Number)) 203 (Pairof String 204 (Pairof String 205 (Pairof String 206 (Pairof String 207 (Pairof String Null)))))) 208 209 #;(test-expander (Let* ([String Number] 210 [Number String]) 211 (List Number String)) 212 (List Number Number)) 213 (void))) 214 215 ;; Test ":" 216 (begin 217 (: c0 `(2 "abc" #,,(Pairof (U 'x 'y) (U 'y 'z)) #(1 "b" x) d)) 218 (define c0 '(2 "abc" #,(x . z) #(1 "b" x) d)) 219 220 (let () 221 (define-type-expander (Repeat stx) 222 (syntax-case stx () 223 [(_ t n) #`(List #,@(map (λ (x) #'t) 224 (range (syntax->datum #'n))))])) 225 226 (: x (→ (Repeat Number 5))) 227 (define (x) (list 1 2 3 4 5)) 228 (check-equal? (x) '(1 2 3 4 5)))) 229 230 ;; Test define-type 231 (let () 232 (define-type-expander (Repeat stx) 233 (syntax-case stx () 234 [(_ t n) #`(List #,@(map (λ (x) #'t) 235 (range (syntax->datum #'n))))])) 236 237 (define-type R5 (Repeat Number 5)) 238 (check-equal? (ann '(1 2 3 4 5) R5) '(1 2 3 4 5))) 239 240 ;; Test define 241 (begin 242 (define d0 243 : `(2 "abc" #,,(Pairof (U 'x 'y) (U 'y 'z)) #(1 "b" x) d) 244 '(2 "abc" #,(x . z) #(1 "b" x) d)) 245 (check-equal? (ann d0 (List 2 246 "abc" 247 (List 'unsyntax 248 (Pairof (U 'x 'y) (U 'y 'z))) 249 (Vector 1 "b" 'x) 'd)) 250 '(2 "abc" (unsyntax (x . z)) #(1 "b" x) d)) 251 252 (: d1 (→ Number (→ Number Number))) 253 (define ((d1 [x : Number]) [y : Number]) : Number (+ x y)) 254 (check-equal? (ann ((d1 2) 3) Number) 5) 255 256 (: d2 (→ Number (→ Number Number))) 257 (define ((d2 [x : Number]) [y : Number]) (+ x y)) 258 (check-equal? (ann ((d2 3) 4) Number) 7) 259 260 (define #:∀ (T) ((d3 [x : T]) [y : T]) : (Pairof T T) (cons x y)) 261 (check-equal? (ann ((d3 'x) 'y) (Pairof Symbol Symbol)) '(x . y))) 262 263 ;; Test lambda 264 (begin 265 (check-equal? ((ann (lambda ([x : Number]) : Number (* x 2)) 266 (→ Number Number)) 267 3) 268 6) 269 (check-equal? ((ann (λ ([x : Number]) : Number (* x 2)) 270 (→ Number Number)) 271 3) 272 6) 273 (check-equal? ((λ x x) 1 2 3) '(1 2 3)) 274 (check-equal? ((λ #:∀ (A) [x : A ...*] : (Listof A) x) 1 2 3) '(1 2 3)) 275 (check-equal? ((λ [x : Number ...*] : (Listof Number) x) 1 2 3) '(1 2 3)) 276 (check-not-exn (λ () 277 (ann (λ #:∀ (A) [x : A ...*] : (Listof A) x) 278 (∀ (A) (→ A * (Listof A)))))) 279 (check-not-exn (λ () 280 (ann (λ #:∀ (A) [x : A *] : (Listof A) x) 281 (∀ (A) (→ A * (Listof A)))))) 282 (check-not-exn (λ () 283 (ann (λ #:∀ (A ...) ([l : (List A ... A)]) : (List A ... A) 284 l) 285 (∀ (A ...) (→ (List A ... A) (List A ... A)))))) 286 (check-not-exn (λ () 287 (ann (λ #:∀ (A ...) [l : (List A ... A) *] 288 : (Listof (List A ... A)) 289 l) 290 (∀ (A ...) (→ (List A ... A) * 291 (Listof (List A ... A))))))) 292 (check-not-exn (λ () 293 (ann (λ #:∀ (A ...) [l : (List A ... A) ...*] 294 : (Listof (List A ... A)) 295 l) 296 (∀ (A ...) (→ (List A ... A) * 297 (Listof (List A ... A)))))))) 298 299 ;; Test struct 300 (begin 301 (struct s0 ()) 302 (struct s1 ([x : Number])) 303 (struct s2 ([x : Number] [y : Number])) 304 (struct s3 ([x : Number] [y : Number]) #:transparent) 305 (struct s4 () #:transparent) 306 (struct (A B) s5 ([x : A] [y : B]) #:transparent) 307 (struct (A B) s6 () #:transparent) 308 (struct s7 s2 ([z : String]) #:transparent) 309 (struct (A) s8 s3 ([z : A]) #:transparent) 310 (struct (A B C) s9 s5 ([z : C]) #:transparent) 311 (struct (A B C) s10 s2 ([z : C]) #:transparent) 312 (struct (A B C) s11 s5 ([z : C])) 313 314 (check (λ (a b) (not (equal? a b))) (s0) (s0)) 315 (check-equal? (s1-x (s1 123)) 123) 316 (check-equal? (s2-x (s2 2 3)) 2) 317 (check-equal? (s2-y (s2 2 3)) 3) 318 (check-equal? (s3-x (s3 4 5)) 4) 319 (check-equal? (s3-y (s3 4 5)) 5) 320 (check-equal? (s4) (s4)) 321 (check-equal? (s5-x (s5 6 7)) 6) 322 (check-equal? (s5-y (s5 6 7)) 7) 323 (check-equal? (s5 6 7) (s5 6 7)) 324 (check-equal? ((inst s5 Number String) 6 "g") (s5 6 "g")) 325 (check-equal? (s6) (s6)) 326 (check-equal? ((inst s6 Number String)) (s6)) 327 328 ;(check-equal? (s7-x (s7 -1 -2 "c") -1)) 329 ;(check-equal? (s7-y (s7 -1 -2 "c") -2)) 330 (check-equal? (s7-z (s7 -1 -2 "c")) "c") 331 (check-equal? (s2-x (s7 -1 -2 "c")) -1) 332 (check-equal? (s2-y (s7 -1 -2 "c")) -2) 333 (check-not-equal? (s7 -1 -2 "c") (s7 -1 -2 "c")) 334 (check-not-exn (λ () (ann (s7 -1 -2 "c") s2))) 335 (check-true (s2? (s7 -1 -2 "c"))) 336 337 ;(check-equal? (s8-x (s8 -1 -2 "c") -1)) 338 ;(check-equal? (s8-y (s8 -1 -2 "c") -2)) 339 (check-equal? (s8-z (s8 -1 -2 "c")) "c") 340 (check-equal? (s3-x (s8 -1 -2 "c")) -1) 341 (check-equal? (s3-y (s8 -1 -2 "c")) -2) 342 (check-equal? (s8 -1 -2 "c") (s8 -1 -2 "c")) 343 (check-equal? ((inst s8 String) -1 -2 "c") (s8 -1 -2 "c")) 344 (check-not-exn (λ () (ann ((inst s8 String) -1 -2 "c") s3))) 345 (check-true (s3? ((inst s8 String) -1 -2 "c"))) 346 347 ;(check-equal? (s9-x (s9 8 9 10)) 8) 348 ;(check-equal? (s9-y (s9 8 9 10)) 9) 349 (check-equal? (s9-z (s9 8 9 10)) 10) 350 (check-equal? (s5-x (s9 8 9 10)) 8) 351 (check-equal? (s5-y (s9 8 9 10)) 9) 352 (check-equal? (s9 8 9 10) (s9 8 9 10)) 353 ;; Bug https://github.com/racket/typed-racket/issues/451 354 ;(check-not-exn (λ () (ann ((inst s9 Number Symbol String) 8 'i "j") 355 ; (Struct s5)))) 356 (check-not-exn (λ () (ann ((inst s9 Number Symbol String) 8 'i "j") 357 (Struct (s5 Number Symbol))))) 358 (check-not-exn (λ () (ann ((inst s9 Number Symbol String) 8 'i "j") 359 (s5 Number Symbol)))) 360 (check-not-exn (λ () (ann ((inst s9 Number Symbol String) 8 'i "j") 361 (s5 Any Any)))) 362 (check-true (s5? ((inst s9 Number Symbol String) -1 'i "j"))) 363 (check-not-equal? (s10 11 12 13) (s10 11 12 13)) 364 (check-not-equal? (s11 14 15 16) (s11 14 15 16))) 365 366 ;; Test define-struct/exec 367 (begin 368 (define-struct/exec se0 () 369 ;[(λ (self v) (cons self v)) : (∀ (A) (→ se0 A (Pairof se0 A)))]) 370 [(λ (self v) (cons self v)) : (→ se0 Any (Pairof se0 Any))]) 371 (define-struct/exec se1 ([x : Number]) 372 ;[(λ (self v) (cons self v)) : (∀ (A) (→ se0 A (Pairof se0 A)))]) 373 [(λ (self v) (cons self v)) : (→ se1 Any (Pairof se1 Any))]) 374 (define-struct/exec se2 ([x : Number] [y : Number]) 375 [(λ (self v) (cons self v)) : (→ se2 Any (Pairof se2 Any))]) 376 (define-struct/exec (se3 se2) ([z : String]) 377 [(λ (self v w) (list self v w)) 378 ;: (∀ (A B) (→ se3 A B (List se2 A B)))]) 379 : (→ se3 Any Any (List se2 Any Any))]) 380 (define-struct/exec (se4 se2) ([z : String]) 381 [(λ (self v w) (list self v w)) 382 ;: (∀ (A B) (→ se4 A B (List se2 A B)))]) 383 : (→ se4 Any (→ Number Number) (List se2 Any (→ Number Number)))]) 384 385 (check (λ (a b) (not (equal? a b))) (se0) (se0)) 386 (check-equal? (cdr ((se0) 'a)) 'a) 387 (check-not-exn (λ () (ann (car ((se0) 'a)) se0))) 388 (check-true (se0? (car ((se0) 'a)))) 389 390 (check (λ (a b) (not (equal? a b))) (se1 123) (se1 123)) 391 (check-equal? (se1-x (se1 123)) 123) 392 (check-equal? (se1-x (car ((se1 123) 'b))) 123) 393 (check-equal? (cdr ((se1 123) 'b)) 'b) 394 (check-not-exn (λ () (ann (car ((se1 123) 'b)) se1))) 395 (check-true (se1? (car ((se1 123) 'b)))) 396 397 (check (λ (a b) (not (equal? a b))) (se2 2 3) (se2 2 3)) 398 (check-equal? (se2-x (se2 2 3)) 2) 399 (check-equal? (se2-y (se2 2 3)) 3) 400 (check-equal? (se2-x (car ((se2 2 3) 'c))) 2) 401 (check-equal? (se2-y (car ((se2 2 3) 'c))) 3) 402 (check-equal? (cdr ((se2 2 3) 'c)) 'c) 403 (check-not-exn (λ () (ann (car ((se2 2 3) 'c)) se2))) 404 (check-true (se2? (car ((se2 2 3) 'c)))) 405 406 (check (λ (a b) (not (equal? a b))) (se3 4 5 "f") (se3 4 5 "f")) 407 (check-equal? (se2-x (se3 4 5 "f")) 4) 408 (check-equal? (se2-y (se3 4 5 "f")) 5) 409 (check-equal? (se3-z (se3 4 5 "f")) "f") 410 (check-equal? (se2-x (car ((se3 4 5 "f") 'd 'e))) 4) 411 (check-equal? (se2-y (car ((se3 4 5 "f") 'd 'e))) 5) 412 (check-equal? (let ([ret : Any (car ((se3 4 5 "f") 'd 'e))]) 413 (if (se3? ret) 414 (se3-z ret) 415 "wrong type!")) 416 "f") 417 (check-equal? (cadr ((se3 4 5 "f") 'd 'e)) 'd) 418 (check-equal? (caddr ((se3 4 5 "f") 'd 'e)) 'e) 419 (check-equal? ((caddr ((se4 4 5 "f") 'd (λ ([x : Number]) (* x 2)))) 12) 420 24) 421 (check-not-exn (λ () (ann (car ((se3 4 5 "f") 'd 'e)) se2))) 422 (check-true (se2? (car ((se3 4 5 "f") 'd 'e)))) 423 (check-true (se3? (car ((se3 4 5 "f") 'd 'e))))) 424 425 ;; Test ann 426 (let () 427 (define-type-expander (Repeat stx) 428 (syntax-case stx () 429 [(_ t n) #`(List #,@(map (λ (x) #'t) 430 (range (syntax->datum #'n))))])) 431 (check-equal? (ann (ann '(1 2 3) 432 (Repeat Number 3)) 433 (List Number Number Number)) 434 '(1 2 3))) 435 436 ;; Test inst 437 (let () 438 (define-type-expander (Repeat stx) 439 (syntax-case stx () 440 [(_ t n) #`(List #,@(map (λ (x) #'t) 441 (range (syntax->datum #'n))))])) 442 443 (: f (∀ (A B C D) (→ (Pairof A B) (Pairof C D) (List A C B D)))) 444 (define (f x y) (list (car x) (car y) (cdr x) (cdr y))) 445 446 (check-equal? ((inst f 447 (Repeat Number 3) 448 (Repeat String 2) 449 (Repeat 'x 1) 450 (Repeat undefined-type 0)) 451 '((1 2 3) . ("a" "b")) 452 '((x) . ())) 453 '((1 2 3) (x) ("a" "b") ()))) 454 455 ;; Test let 456 (begin 457 (check-equal? (ann (let loop-id ([x 1]) 458 (if (equal? x 2) 459 x 460 (loop-id 2))) 461 Any) 462 2) 463 (check-equal? (let () 'x) 'x) 464 (check-equal? (ann (let #:∀ (T) ([a : T 3] 465 [b : (Pairof T T) '(5 . 7)]) 466 (cons a b)) 467 (Pairof Number (Pairof Number Number))) 468 '(3 5 . 7))) 469 470 ;; Test let* 471 (let () 472 (define-type-expander (Repeat stx) 473 (syntax-case stx () 474 [(_ t n) #`(List #,@(map (λ (x) #'t) 475 (range (syntax->datum #'n))))])) 476 477 (check-equal? (let* ([x* : (Repeat Number 3) '(1 2 3)] 478 [y* : (Repeat Number 3) x*]) 479 y*) 480 '(1 2 3))) 481 482 ;; Test let-values 483 (let () 484 (define-type-expander (Repeat stx) 485 (syntax-case stx () 486 [(_ t n) #`(List #,@(map (λ (x) #'t) 487 (range (syntax->datum #'n))))])) 488 489 (check-equal? (ann (let-values 490 ([([x : (Repeat Number 3)]) 491 (list 1 2 3)]) 492 (cdr x)) 493 (List Number Number)) 494 '(2 3)) 495 496 (check-equal? (ann (let-values 497 ([([x : (Repeat Number 3)] [y : Number]) 498 (values (list 1 2 3) 4)]) 499 (cons y x)) 500 (Pairof Number (List Number Number Number))) 501 '(4 . (1 2 3))) 502 503 (check-equal? (ann (let-values 504 ([(x y) 505 (values (list 1 2 3) 4)]) 506 (cons y x)) 507 (Pairof Number (List Number Number Number))) 508 '(4 . (1 2 3)))) 509 510 ;; Test make-predicate 511 (let () 512 (define-type-expander (Repeat stx) 513 (syntax-case stx () 514 [(_ t n) #`(List #,@(map (λ (x) #'t) 515 (range (syntax->datum #'n))))])) 516 (check-equal? ((make-predicate (Repeat Number 3)) '(1 2 3)) #t) 517 (check-equal? ((make-predicate (Repeat Number 3)) '(1 "b" 3)) #f)) 518 519 ;; row-inst 520 (let-syntax ([when-row-inst-is-defined 521 (λ (stx) 522 (syntax-case stx () 523 [(_ body) 524 (if (or (identifier-binding #'row-inst) 525 (version<=? "6.7" (version))) 526 #'body 527 #'(void))]))]) 528 (when-row-inst-is-defined 529 (let () 530 ;; Example taken from the docs 531 (: id (All (r #:row) 532 (-> (Class #:row-var r) (Class #:row-var r)))) 533 (define (id cls) cls) 534 (define result ((row-inst id (Row (field [x Integer]))) 535 (class object% (super-new) (field [x : Integer 0])))) 536 (ann result (Class (field (x Integer)))) 537 (void)))) 538 539 ;; Tests written while debugging 540 (begin 541 (let () 542 (define-type-expander flob 543 (λ (stx) #'(All (abc) (List abc)))) 544 545 (ann '(a) ((flob) Symbol)) 546 547 (ann '(42) ((Let ([flob (Λ (_ arg) 548 #'((∀ (abc) 549 (List abc)) arg))]) 550 flob) 551 Integer)) 552 553 (ann '(1 2 3) ((∀ (abc) 554 (Listof abc)) 555 Integer)) 556 557 (ann '(1 2 3) ((Let () 558 (∀ (abc) 559 (Listof abc))) 560 Integer)) 561 (void)) 562 563 (let () 564 (test-expander 565 ((Let () (∀ (A1) (Let () A1))) Number) 566 Number)) 567 568 (let () 569 (ann '(1 2 3) (Listof Integer)) 570 571 (define-type (poly1 ty) 572 (Listof ty)) 573 574 (ann '(1 2 3) (poly1 Integer)) 575 576 (define-type poly2 577 (∀ (ty) 578 (Listof ty))) 579 580 ;; invalid starting from racket 9.0 (dubious semantics before that, a ∀ is technically not a type function and uses a different eliminator, was allowed for convenience I guess. 581 ;;(ann '(1 2 3) (poly2 Integer)) 582 583 ;; type-expander manages to salvage this, but is invalid in racket 9.0. Should probably fail for consistency. 584 (ann '(1 2 3) ((∀ (ty) 585 (Listof ty)) 586 Integer)) 587 588 ;; type-expander manages to salvage this, but is invalid in racket 9.0. Should probably fail for consistency. 589 (ann '(1 2 3) ((Let () 590 (∀ (ty) 591 (Listof ty))) 592 Integer)) 593 594 (void)) 595 596 (define-for-syntax (test-use/def stx def expected-use expected-def) 597 (let ([actual-use (syntax->datum 598 (apply-type-expander (datum->syntax stx 'Quux) 599 (datum->syntax stx 'Quux)))] 600 [actual-def (syntax->datum 601 (apply-type-expander def def))]) 602 (check-equal? actual-use expected-use) 603 (check-equal? actual-def expected-def))) 604 605 (let () 606 (define-type-expander (Foo stx) #'Integer) 607 (define-type-expander (Bar stx) #'Integer) 608 (define-type-expander (Quux stx) #'Integer) 609 610 (define-type mytype1 611 (Let ([Foo (Λ (_ T) 612 (test-use/def #'T #'Quux 'Integer 'Integer) 613 #'T)]) 614 (Foo Quux))) 615 616 (define-type mytype23 617 (Let ([Quux String]) 618 (Let ([Foo (Λ (_ T) 619 (test-use/def #'T #'Quux 'String 'String) 620 #'T)]) 621 (Foo (∀ (A) 622 (Let ([Bar (Λ (_ T) 623 (test-use/def #'T #'Quux 'String 'String) 624 #'T)]) 625 (Bar (Listof A)))))))) 626 627 (define-type mytype45 628 (Let ([Foo (Λ (_ T) 629 (test-use/def #'T #'Quux 'String 'Integer) 630 #'T)]) 631 (Let ([Quux String]) 632 (Foo (∀ (A) 633 (Let ([Bar (Λ (_ T) 634 (test-use/def #'T #'Quux 'String 'String) 635 #'T)]) 636 (Bar (Listof A)))))))) 637 638 (define-type mytype67 639 (Let ([Foo (Λ (_ T) 640 (test-use/def #'T #'Quux 'Integer 'Integer) 641 #'T)]) 642 (Foo (Let ([Quux String]) 643 (∀ (A) 644 (Let ([Bar (Λ (_ T) 645 (test-use/def #'T #'Quux 'String 'String) 646 #'T)]) 647 (Bar (Listof A)))))))) 648 649 (define-type mytype89 650 (Let ([Foo (Λ (_ T) 651 (test-use/def #'T #'Quux 'Integer 'Integer) 652 #'T)]) 653 (Foo (∀ (A) 654 (Let ([Quux String]) 655 (Let ([Bar (Λ (_ T) 656 (test-use/def #'T #'Quux 'String 'String) 657 #'T)]) 658 (Bar (Listof A)))))))) 659 660 (void)) 661 662 (let () 663 (test-expander ((Let ([F (Λ (_ T) #'T)]) F) String) 664 String) 665 (test-expander ((Let ([F (Λ (_ T) #'(List T))]) F) String) 666 (List String))) 667 668 ;; Please don't ever do that in practice :) ! 669 (let () 670 (test-expander (Let ([Loot Number]) 671 ((Let ([Loot Let]) Loot) ([AAA Number]) 672 AAA)) 673 Number) 674 (test-expander (Let ([Loot Number]) 675 ((Let ([Loot Let]) Loot) ([Let Loot]) 676 Let)) 677 Number) 678 (test-expander (Let ([Loot Number]) 679 ((Let ([Loot Let]) Loot) ([Loot String]) 680 Loot)) 681 String))) 682 683 ;; more tests 684 (begin 685 (test-expander ((∀ (A) ((∀ (A) ((∀ (A) ((∀ (A) A) A)) A)) A)) Number) 686 Number) 687 (test-expander (Let ([A Number]) 688 (Let ([A A]) 689 (Let ([A A]) 690 (Let ([A A]) 691 A)))) 692 Number) 693 (test-expander (Let* ([A Number] 694 [A A] 695 [A A] 696 [A A] 697 [A A]) 698 A) 699 Number) 700 (test-expander (Let* ([A Number] 701 [A (List A)] 702 [A (Pairof A A)] 703 [A (Vector A)] 704 [A (Set A)]) 705 A) 706 (Set (Vector (Pairof (List Number) (List Number))))) 707 708 ;; Adjusted from http://www.cs.utah.edu/~mflatt/scope-sets/ 709 ;; #%28part._.Macro_.Definitions_in_a_.Recursive_.Scope%29 710 (test-expander (Letrec ([Identity (Λ (_ misc-id) 711 #'(∀ (X) 712 (Let ([misc-id String]) 713 X)))]) 714 ((Identity X) Number)) 715 Number) 716 (test-expander (Letrec ([Identity (Λ (_ misc-id) 717 #'(∀ (misc-id) 718 (Let ([X String]) 719 misc-id)))]) 720 ((Identity X) Number)) 721 Number) 722 (test-expander (Letrec ([GetY (Λ (_ misc-id) 723 (datum->syntax #'misc-id 'Y))]) 724 (Let ([Y Number]) (GetY X))) 725 Number) 726 (test-expander (Letrec ([GetY (Λ (_ misc-id) 727 (datum->syntax #'misc-id 'Y))]) 728 ((∀ (Y) (GetY X)) Number)) 729 Number)) 730 731 ;; Tests for Syntax 732 (let () 733 (test-expander #'a (Syntaxof 'a)) 734 (test-expander #'(a) (Syntaxof (List (Syntaxof 'a)))) 735 (test-expander #'(a . b) (Syntaxof (Pairof (Syntaxof 'a) (Syntaxof 'b)))) 736 (test-expander #'(a . (b)) 737 (Syntaxof (Pairof (Syntaxof 'a) 738 (Syntaxof (List (Syntaxof 'b)))))) 739 (test-expander #'(a b) (Syntaxof (List (Syntaxof 'a) (Syntaxof 'b)))) 740 (test-expander #'(a b . c) 741 (Syntaxof (List* (Syntaxof 'a) (Syntaxof 'b) (Syntaxof 'c)))) 742 (test-expander #'(a b . (c)) 743 (Syntaxof (List* (Syntaxof 'a) 744 (Syntaxof 'b) 745 (Syntaxof (List (Syntaxof 'c))))))) 746 747 ;; Small typo 748 (let () 749 (test-expander ((No-Expand List) 'a 'b) (List 'a 'b)))