Modified the for: macros to use sequence types.

original commit: 0741b48c99e190a31365c2fe2f2cd927d9561bb2
This commit is contained in:
Vincent St-Amour 2010-06-09 11:41:58 -04:00
parent ee7d9e61dd
commit e0219a6f8f
4 changed files with 72 additions and 28 deletions

View File

@ -18,7 +18,7 @@
(with-output-to-string
(lambda ()
(for: : Void
((i : Exact-Positive-Integer '(1 2 3))
((i : Integer '(1 2 3))
(j : Char "abc")
#:when (odd? i)
(k : True #(#t #t))
@ -32,22 +32,22 @@
(check equal?
(for/list: : (Listof Integer)
((i : Exact-Positive-Integer '(1 2 3))
(j : Exact-Positive-Integer '(10 20 30))
((i : Integer '(1 2 3))
(j : Integer '(10 20 30))
#:when (odd? i))
(+ i j 10))
'(21 43))
(check equal?
(for/or: : Boolean
((i : Exact-Positive-Integer '(1 2 3)))
((i : Integer '(1 2 3)))
(>= i 3))
#t)
(check equal?
(for/or: : Boolean
((i : Exact-Positive-Integer '(1 2 3))
(j : Exact-Positive-Integer '(2 1 3)))
((i : Integer '(1 2 3))
(j : Integer '(2 1 3)))
(>= i j))
#t)
@ -56,9 +56,9 @@
(for/lists: : (values (Listof Integer) (Listof Integer))
((x : (Listof Integer))
(y : (Listof Integer)))
((i : Exact-Positive-Integer '(1 2 3))
((i : Integer '(1 2 3))
#:when #t
(j : Exact-Positive-Integer '(10 20 30))
(j : Integer '(10 20 30))
#:when (> j 12))
(values i j))])
(append x y))
@ -67,19 +67,19 @@
(check =
(for/fold: : Integer
((acc : Integer 0))
((i : Exact-Positive-Integer '(1 2 3))
(j : Exact-Positive-Integer '(10 20 30)))
((i : Integer '(1 2 3))
(j : Integer '(10 20 30)))
(+ acc i j))
66)
(check =
(for/fold: : Integer
((acc : Integer 0))
((i : Exact-Positive-Integer '(1 2 3))
((i : Integer '(1 2 3))
#:when (even? i)
(j : Exact-Positive-Integer '(10 20 30))
(j : Integer '(10 20 30))
#:when #t
(k : Exact-Positive-Integer '(100 200 300)))
(k : Integer '(100 200 300)))
(+ acc i j k))
1998)
@ -87,8 +87,8 @@
(with-output-to-string
(lambda ()
(for*: : Void
((i : Exact-Positive-Integer '(1 2 3))
(j : Exact-Positive-Integer '(10 20 30)))
((i : Integer '(1 2 3))
(j : Integer '(10 20 30)))
(display (list i j)))))
"(1 10)(1 20)(1 30)(2 10)(2 20)(2 30)(3 10)(3 20)(3 30)")
@ -97,8 +97,8 @@
(for*/lists: : (values (Listof Integer) (Listof Integer))
((x : (Listof Integer))
(y : (Listof Integer)))
((i : Exact-Positive-Integer '(1 2 3))
(j : Exact-Positive-Integer '(10 20 30))
((i : Integer '(1 2 3))
(j : Integer '(10 20 30))
#:when (> j 12))
(values i j))])
(append x y))
@ -107,9 +107,9 @@
(check =
(for*/fold: : Integer
((acc : Integer 0))
((i : Exact-Positive-Integer '(1 2 3))
((i : Integer '(1 2 3))
#:when (even? i)
(j : Exact-Positive-Integer '(10 20 30))
(k : Exact-Positive-Integer '(100 200 300)))
(j : Integer '(10 20 30))
(k : Integer '(100 200 300)))
(+ acc i j k))
1998)

View File

@ -59,3 +59,23 @@
(for/last: : (Option Integer)
((i : Exact-Positive-Integer '(1 2 3)))
i)
;; unlike the usual cases with #:when clauses, inference does something, but does it wrong
(for/list: : (Listof Integer)
(#:when #t
(i : Exact-Positive-Integer '(1 2 3))
(j : Exact-Positive-Integer '(10 20 30)))
(+ i j 10))
;; that same bug makes for/hash:, for/hasheq: and for/hasheqv: unusable
;; this infers Nothing for the type of the elements of the HashTable
;; since they don't work, these functions are not currently documented
(for/hash: : (HashTable Integer Char)
((i : Exact-Positive-Integer '(1 2 3))
(j : Char "abc"))
(values i j))
;; same thing for for/and:
(for/and: : Boolean
((i : Exact-Positive-Integer '(1 2 3)))
(< i 3))

View File

@ -2,18 +2,25 @@
(require syntax/parse
"annotate-classes.rkt"
(for-template racket/base))
(for-template racket/base
"base-types-new.rkt"))
(provide (all-defined-out))
(define-splicing-syntax-class for-clause
;; single-valued seq-expr
(pattern (var:annotated-name seq-expr:expr)
#:with (expand ...) (list #'(var.ann-name seq-expr)))
#:with (expand ...) (list #`(var.ann-name
#,(syntax-property #'seq-expr
'type-ascription
#'(Sequenceof var.ty)))))
;; multi-valued seq-expr
;; currently disabled because it triggers an internal error in the typechecker
#;(pattern (((v:annotated-name) ...) seq-expr:expr)
#:with (expand ...) (list #'((v.ann-name ...) seq-expr)))
#:with (expand ...) (list #`((v.ann-name ...)
#,(syntax-property #'seq-expr
'type-ascription
#'(Sequenceof (values v.ty ...))))))
;; when clause
(pattern (~seq #:when guard:expr)
#:with (expand ...) (list #'#:when #'guard)))
@ -22,11 +29,19 @@
(define-splicing-syntax-class for*-clause
;; single-valued seq-expr
(pattern (var:annotated-name seq-expr:expr)
#:with (expand ...) (list #'(var.ann-name seq-expr) #'#:when #'#t))
#:with (expand ...) (list #`(var.ann-name
#,(syntax-property #'seq-expr
'type-ascription
#'(Sequenceof var.ty)))
#'#:when #'#t))
;; multi-valued seq-expr
;; currently disabled because it triggers an internal error in the typechecker
#;(pattern (((v:annotated-name) ...) seq-expr:expr)
#:with (expand ...) (list #'((v.ann-name ...) seq-expr) #'#:when #'#t))
#:with (expand ...) (list #`((v.ann-name ...)
#,(syntax-property #'seq-expr
'type-ascription
#'(Sequenceof (values v.ty ...))))
#'#:when #'#t))
;; when clause
(pattern (~seq #:when guard:expr)
#:with (expand ...) (list #'#:when #'guard)))

View File

@ -392,11 +392,20 @@ This file defines two sorts of primitives. All of them are provided into any mod
(let loop ((clauses #'clauses))
(define-syntax-class for-clause
;; single-valued seq-expr
;; unlike the definitions in for-clauses.rkt, this does not include
;; #:when clauses, which are handled separately here
(pattern (var:annotated-name seq-expr:expr)
#:with expand #'(var.ann-name seq-expr))
#:with expand #`(var.ann-name
#,(syntax-property #'seq-expr
'type-ascription
#'(Sequenceof var.ty))))
;; multi-valued seq-expr
(pattern ((v:annotated-name ...) seq-expr:expr)
#:with expand #'((v.ann-name ...) seq-expr)))
;; currently disabled because it triggers an internal error in the typechecker
#;(pattern ((v:annotated-name ...) seq-expr:expr)
#:with expand #`((v.ann-name ...)
#,(syntax-property #'seq-expr
'type-ascription
#'(Sequenceof (values v.ty ...))))))
(syntax-parse clauses
[(head:for-clause next:for-clause ... #:when rest ...)
(syntax-property