这是indexloc提供的服务,不要输入任何密码
Skip to content

[for] Support #:do and #:splice #1437

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,15 @@ To see how to declare a type for @racket[add-map], see the
[for-clause [id : t seq-expr]
[(binding ...) seq-expr]
[id seq-expr]
@code:line[#:when guard]]
@code:line[#:when guard]
@code:line[#:unless guard]
@code:line[#:do [do-body ...]]
break-clause
@code:line[#:splice (splicing-id . form)]]
[binding id
[id : t]])]{
[id : t]]
[break-clause @code:line[#:break guard]
@code:line[#:final guard]])]{
Like @|for-id| from @racketmodname[racket/base], but each @racket[id] has the associated type
@racket[t]. The latter @racket[_ann-maybe] will be used first, and then the previous one.
Since the return type is always @racket[Void],
Expand Down
4 changes: 2 additions & 2 deletions typed-racket-lib/typed-racket/base-env/for-clauses.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
#:with (expand* ...) (list (quasisyntax/loc #'c
((v.ann-name ...) seq-expr.e))
#'#:when #''#t))
(pattern (~seq (~and kw (~or #:when #:unless #:break #:final)) guard:expr)
#:with (expand ...) (list #'kw #'guard)
(pattern (~seq (~and kw (~or #:when #:unless #:break #:final #:do #:splice)) expr:expr)
#:with (expand ...) (list #'kw #'expr)
#:with (expand* ...) #'(expand ...)))

(define-syntax-class for-clauses
Expand Down
27 changes: 16 additions & 11 deletions typed-racket-lib/typed-racket/base-env/prims.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -308,16 +308,29 @@ the typed racket language.
(pattern (~seq (~and kw (~or #:break #:final)) guard-expr:expr)
#:with (expand ...) #'(kw guard-expr)))
(define-syntax-class for-kw
(pattern #:when)
(pattern #:unless)
(pattern #:do)
(pattern #:splice))
(define-syntax-class for-when
(pattern #:when
#:with replace-with #'when)
(pattern #:unless
#:with replace-with #'unless))
(syntax-parse clauses
[(head:for-clause next:for-clause ... kw:for-kw guard b:break-clause ... rest ...)
[(when:for-when guard) ; we end on a keyword clause
(quasisyntax/loc stx
(when.replace-with guard
#,@body))]
[(when:for-when guard rest ...)
(quasisyntax/loc stx
(when.replace-with guard
#,(loop #'(rest ...))))]
[(head:for-clause ... kw:for-kw expr b:break-clause ... rest ...)
(add-ann
(quasisyntax/loc stx
(for
(head.expand ... next.expand ... ... kw guard b.expand ... ...)
(head.expand ... ... kw expr b.expand ... ...)
#,(loop #'(rest ...))))
#'Void)]
[(head:for-clause ...) ; we reached the end
Expand All @@ -326,15 +339,7 @@ the typed racket language.
(for
(head.expand ... ...)
#,@body))
#'Void)]
[(kw:for-kw guard) ; we end on a keyword clause
(quasisyntax/loc stx
(kw.replace-with guard
#,@body))]
[(kw:for-kw guard rest ...)
(quasisyntax/loc stx
(kw.replace-with guard
#,(loop #'(rest ...))))])))]))
#'Void)])))]))

(begin-for-syntax
(define-splicing-syntax-class optional-standalone-annotation*
Expand Down
31 changes: 31 additions & 0 deletions typed-racket-test/succeed/for.rkt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#lang typed/scheme

(require (for-syntax racket/base))

(: check (All (a) ((a a -> Boolean) a a -> Boolean)))
;; Simple check function as RackUnit doesn't work in Typed Scheme (yet)
(define (check f a b)
Expand Down Expand Up @@ -50,6 +52,35 @@
(display (list i j k)))))
"(1 a #t)(1 a #t)(3 c #t)(3 c #t)")

(check string=?
(with-output-to-string
(lambda ()
(for: : Void (#:do [(display #"0123456789")])
(void))))
"0123456789")
(check string=?
(with-output-to-string
(lambda ()
(for: : Void
([i '(1 2 3)]
#:do [(define neg-i (- i))]
[j (in-list (list neg-i 0 i))])
(display j))))
"-101-202-303")

(check string=?
(with-output-to-string
(lambda ()
(define-splicing-for-clause-syntax cross3
(lambda (stx)
(syntax-case stx ()
[(_ n m) #'([n (in-range 3)]
#:when #t
[m (in-range 3)])])))
(for: : Void (#:splice (cross3 m n))
(display (+ m n)))))
"012123234")

(check equal?
(for/list: : (Listof Integer) ([i : Integer (in-range 10)]) i)
'(0 1 2 3 4 5 6 7 8 9))
Expand Down