[racket-users] web-server - stream file uploads? [was ... servlet performance ...]
On Fri, 1 Sep 2017 14:38:21 -0400, Neil Van Dykewrote: > ... *except when a GC cycle kicks in*. Speaking of web servers and GC ... I have a http web-server application that needs to be able to up/down load fairly large files. The application is somewhat memory constrained, and I'd like to handle these large data transfers in chunks using (relatively) small buffers. Outgoing is not [much of] a problem because the client TCP connection is available in response/output ... but with incoming data, the web-server framework has slurped in everything before my code even runs. Is there a way in the web-server to stream incoming data? Or maybe to get at the request before the (multipart) form data is read in? George -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Racket Web servlet performance benchmarked and compared
Oh yeah, contention from simultaneous requests, if you're doing that, can also complicate your numbers. Adjusting `#:scgi-max-allow-wait` might be a quick way to see whether that changes your numbers. (Hitting a limit here could give you better numbers, or worse numbers, but removing a limit being hit should change the numbers.) You can also run Wireshark or "tcpdump", to be certain of what's going on at the packet level, but that can be time-consuming to trace through. Neil Van Dyke wrote on 09/01/2017 02:38 PM: Thank you very much for doing this work, D. Bohdan. If I'm reading these results quickly, and if my guess about the distribution is correct, then it looks like Racket SCGI+nginx *might* actually have the best times of any of your tested combinations *except when a GC cycle kicks in*. results/scgi.txt-Percentage of the requests served within a certain time (ms) results/scgi.txt- 50% 3 results/scgi.txt- 66% 4 results/scgi.txt- 75% 4 results/scgi.txt- 80% 5 results/scgi.txt- 90% 7 results/scgi.txt- 95% 11 results/scgi.txt- 98% 1018 results/scgi.txt- 99% 1030 results/scgi.txt- 100% 55256 (longest request) If GC is indeed the cause, if you avoid or reduce the GC hits that are killing you 5% of the time, then maybe 100% of your requests are fast. (I suggest looking at avoiding/reducing GC hits holistically, in an application-specific way, since there's lots of things you can do, depending, and there are costs and benefits. One very likely situation is that there are inefficiencies in the application code itself that are the bottleneck, and it's best to take a look at those before focusing on where the bottleneck moves next. That familiarization with the application code can also help you decide how to address any bottlenecks external to it.) This performance of Racket SCGI+nginx relative to the others you tested is surprising to me, since I made the Racket `scgi` package for particular non-performance requirements, and performance was really secondary. (If I were prioritizing speed higher, I suspect I could make serving much faster, doing it a different way, and then micro-optimizing on top of that.) Not to look a gift horse in the mouth, but it's possible that something else was going on, to give surprisingly good numbers. For example, often, errors can cause good performance numbers. Sometimes I used JMeter instead of `ab` to rule out that cause of bad numbers in performance testing (as well as to implement some testing). Also, the bad numbers could be something else, like the OS pushing into swap, sporadic network latency (though looks like you might've controlled for that one), or some other OS/hardware/network burp outside of your Racket process(es). I'd want to have a better understanding of these numbers before Racketeers started either bragging or donning burlap sacks of shame. :) -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Racket Web servlet performance benchmarked and compared
Thank you very much for doing this work, D. Bohdan. If I'm reading these results quickly, and if my guess about the distribution is correct, then it looks like Racket SCGI+nginx *might* actually have the best times of any of your tested combinations *except when a GC cycle kicks in*. results/scgi.txt-Percentage of the requests served within a certain time (ms) results/scgi.txt- 50% 3 results/scgi.txt- 66% 4 results/scgi.txt- 75% 4 results/scgi.txt- 80% 5 results/scgi.txt- 90% 7 results/scgi.txt- 95% 11 results/scgi.txt- 98% 1018 results/scgi.txt- 99% 1030 results/scgi.txt- 100% 55256 (longest request) If GC is indeed the cause, if you avoid or reduce the GC hits that are killing you 5% of the time, then maybe 100% of your requests are fast. (I suggest looking at avoiding/reducing GC hits holistically, in an application-specific way, since there's lots of things you can do, depending, and there are costs and benefits. One very likely situation is that there are inefficiencies in the application code itself that are the bottleneck, and it's best to take a look at those before focusing on where the bottleneck moves next. That familiarization with the application code can also help you decide how to address any bottlenecks external to it.) This performance of Racket SCGI+nginx relative to the others you tested is surprising to me, since I made the Racket `scgi` package for particular non-performance requirements, and performance was really secondary. (If I were prioritizing speed higher, I suspect I could make serving much faster, doing it a different way, and then micro-optimizing on top of that.) Not to look a gift horse in the mouth, but it's possible that something else was going on, to give surprisingly good numbers. For example, often, errors can cause good performance numbers. Sometimes I used JMeter instead of `ab` to rule out that cause of bad numbers in performance testing (as well as to implement some testing). Also, the bad numbers could be something else, like the OS pushing into swap, sporadic network latency (though looks like you might've controlled for that one), or some other OS/hardware/network burp outside of your Racket process(es). I'd want to have a better understanding of these numbers before Racketeers started either bragging or donning burlap sacks of shame. :) -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Re: Mapping over pattern variables
I recommend splitting this macro in two so you don't need to escape out of the template language: (define-syntax (macro stx) (syntax-parse stx [(_ (var1:id ...) (~and vars (var2:id ...)) #'(begin (macro/var2 (#freeze var1) vars) ...)])) (define-syntax (macro/var2 stx (syntax-parse stx [(_ var1/freeze (var2:id ...)) (begin (do-something var1/freeze var2) ...)])) This also lets you get more information out of the macro stepper when debugging, since you'll see two separate expansion steps. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Racket Web servlet performance benchmarked and compared
Hi, everyone. Long time (occasional) reader, first time writer here. In the 5.x days I played with Racket's Web servlets and found them slower than I'd expected. (My exceptions were, admittedly, quite high after seeing how much better Racket performed at other tasks than your average scripting language.) I've decided to try Web servlets out again, but this time to put some rough numbers on the performance with a reproducible benchmark. My benchmark compares Racket's stateful and stateless servlets against the SCGI package for Racket, Caddy (HTTP server written in Go), Flask (Python web microframework), GNU Guile's Web server module, Ring/Compojure (Clojure HTTP middleware/routing library), Plug (Elixir HTTP middleware), and Sinatra (Ruby web microframework). On each of these platforms the benchmark implements a trivial web application that serves around 4K of plain text. It uses ApacheBench to stress it with a configurable number of concurrent connections. The application and ApacheBench are run in separate Docker containers, which lets you tune the memory and the CPU time available to them. I've published the source code for the benchmark at https://gitlab.com/dbohdan/racket-vs-the-world/. It should be straightforward to run on Linux with Docker (but please report any difficulties!). I've attached the results I got on a two-core VM. According to them, Racket's servlets do lag behind everything else but Sinatra. The results are for 100 concurrent connections, which is the default, but the differences in throughput are still very similar with 20 connections and quite similar with just one. I'd appreciate any feedback on these results (do they look reasonable to you?) and the code behind the benchmark (did I miss any crucial bits of configuration for the servlet?). Best, D. Bohdan -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. > grep -A 21 'Requests per second' results/* results/caddy.txt:Requests per second:4294.27 [#/sec] (mean) results/caddy.txt-Time per request: 23.287 [ms] (mean) results/caddy.txt-Time per request: 0.233 [ms] (mean, across all concurrent requests) results/caddy.txt-Transfer rate: 18141.66 [Kbytes/sec] received results/caddy.txt- results/caddy.txt-Connection Times (ms) results/caddy.txt- min mean[+/-sd] median max results/caddy.txt-Connect:01 0.9 0 12 results/caddy.txt-Processing: 0 23 11.2 21 106 results/caddy.txt-Waiting:0 21 10.7 20 102 results/caddy.txt-Total: 0 23 11.0 22 106 results/caddy.txt-WARNING: The median and mean for the initial connection time are not within a normal deviation results/caddy.txt-These results are probably not that reliable. results/caddy.txt- results/caddy.txt-Percentage of the requests served within a certain time (ms) results/caddy.txt- 50% 22 results/caddy.txt- 66% 27 results/caddy.txt- 75% 30 results/caddy.txt- 80% 32 results/caddy.txt- 90% 38 results/caddy.txt- 95% 43 results/caddy.txt- 98% 50 -- results/compojure.txt:Requests per second:4989.57 [#/sec] (mean) results/compojure.txt-Time per request: 20.042 [ms] (mean) results/compojure.txt-Time per request: 0.200 [ms] (mean, across all concurrent requests) results/compojure.txt-Transfer rate: 20659.95 [Kbytes/sec] received results/compojure.txt- results/compojure.txt-Connection Times (ms) results/compojure.txt- min mean[+/-sd] median max results/compojure.txt-Connect:09 92.2 03048 results/compojure.txt-Processing: 0 11 7.2 9 228 results/compojure.txt-Waiting:0 10 7.1 9 228 results/compojure.txt-Total: 1 20 92.8 103067 results/compojure.txt- results/compojure.txt-Percentage of the requests served within a certain time (ms) results/compojure.txt- 50% 10 results/compojure.txt- 66% 13 results/compojure.txt- 75% 14 results/compojure.txt- 80% 16 results/compojure.txt- 90% 20 results/compojure.txt- 95% 25 results/compojure.txt- 98% 33 results/compojure.txt- 99% 53 results/compojure.txt- 100% 3067 (longest request) -- results/flask.txt:Requests per second:1153.20 [#/sec] (mean) results/flask.txt-Time per request: 86.715 [ms] (mean) results/flask.txt-Time per request: 0.867 [ms] (mean, across all concurrent requests) results/flask.txt-Transfer rate: 4799.74 [Kbytes/sec] received results/flask.txt- results/flask.txt-Connection Times (ms) results/flask.txt- min mean[+/-sd] median max results/flask.txt-Connect:00 0.2 0 12 results/flask.txt-Processing: 2 87
Re: [racket-users] Mapping over pattern variables
See also `in-syntax`: http://docs.racket-lang.org/reference/sequences.html?q=in-syntax#%28def._%28%28lib._racket%2Fsequence..rkt%29._in-syntax%29%29 -Philip On Fri, Sep 1, 2017 at 9:25 AM, Jens Axel Søgaardwrote: > One more: > > (begin-for-syntax > (define (in-syntax-list stx) (in-list (syntax->list stx))) > (require (for-syntax racket/base )) > (define-syntax (for*/syntax-list stx) > (syntax-case stx () > [(_for*/syntax-list head (for-clause ...) body-or-break ... body) > >#'(datum->syntax #'stx (cons head (for*/list (for-clause ...) > body-or-break ... body)))]))) > > (define-syntax (macro3 stx) > (syntax-case stx () > [(_ (x ...) (y ...)) > (for*/syntax-list #'begin >([x (in-syntax-list #'(x ...))] > [y (in-syntax-list #'(y ...))]) >(with-syntax ([x x] [y y]) > #'(do-something x y)))])) > > > 2017-09-01 15:57 GMT+02:00 Jens Axel Søgaard : > >> Two variations: >> >> #lang racket >> (require (for-syntax syntax/parse)) >> >> (define (do-something x y) (displayln (list x y))) >> >> (define-syntax-rule (macro (x ...) ys) >> (begin (outer x ys) ...)) >> >> (define-syntax-rule (outer x (y ...)) >> (begin (do-something x y) ...)) >> >> (macro (1 2 3) (4 5)) >> (newline) >> >> (define-syntax (macro2 stx) >> (syntax-parse stx >> [(_macro2 (x ...) ys) >> (with-syntax ([ooo #'(... ...)]) >>#'(begin >>(let () >> (define-syntax-rule (inner (y ooo)) >>(begin (do-something x y) ooo)) >> (inner ys)) >>...))])) >> >> (macro2 (1 2 3) (4 5)) >> >> >> 2017-09-01 15:48 GMT+02:00 Jos Koot : >> >>> How about: >>> >>> (define-syntax (macro stx) >>> (syntax-case stx () >>> [(_ (var1 ...) (var2 ...)) >>> #`(begin >>> #,@(for*/list ((v1 (in-list (syntax->list #'(var1 ... >>>(v2 (in-list (syntax->list #'(var2 ...) >>> #`(do-something #,v1 #,v2)))])) >>> >>> Jos >>> >>> -Original Message- >>> From: racket-users@googlegroups.com [mailto:racket-users@googlegro >>> ups.com] On Behalf Of Sam Waxman >>> Sent: viernes, 01 de septiembre de 2017 11:37 >>> To: Racket Users >>> Subject: [racket-users] Mapping over pattern variables >>> >>> Lets say I have a macro >>> >>> (define-syntax (macro stx) >>> (syntax-parse stx >>> [(_ (var1 ...) (var 2 ...)) >>> #'(begin >>> (begin >>>(do-something (#freeze var1) var2) >>>...) >>> ...)])) >>> >>> and I want to iterate first over var2, and then over var1. So if I type >>> >>> (macro (1 2 3) (1 2)) >>> >>> I should get >>> >>> (begin >>> (begin >>> (do-something 1 1) >>> (do-something 1 2)) >>> (begin >>> (do-something 2 1) >>> (do-something 2 2)) >>> (begin >>> (do-something 3 1) >>> (do-something 3 2))) >>> >>> What do I put where I currently have "#freeze" to tell the expander that >>> I don't want the ... to affect var1? Or do I have to do >>> this manually with syntax->list and mapping functions? >>> >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Racket Users" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to racket-users+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Racket Users" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to racket-users+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> >> >> -- >> -- >> Jens Axel Søgaard >> >> > > > -- > -- > Jens Axel Søgaard > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Mapping over pattern variables
One more: (begin-for-syntax (define (in-syntax-list stx) (in-list (syntax->list stx))) (require (for-syntax racket/base )) (define-syntax (for*/syntax-list stx) (syntax-case stx () [(_for*/syntax-list head (for-clause ...) body-or-break ... body) #'(datum->syntax #'stx (cons head (for*/list (for-clause ...) body-or-break ... body)))]))) (define-syntax (macro3 stx) (syntax-case stx () [(_ (x ...) (y ...)) (for*/syntax-list #'begin ([x (in-syntax-list #'(x ...))] [y (in-syntax-list #'(y ...))]) (with-syntax ([x x] [y y]) #'(do-something x y)))])) 2017-09-01 15:57 GMT+02:00 Jens Axel Søgaard: > Two variations: > > #lang racket > (require (for-syntax syntax/parse)) > > (define (do-something x y) (displayln (list x y))) > > (define-syntax-rule (macro (x ...) ys) > (begin (outer x ys) ...)) > > (define-syntax-rule (outer x (y ...)) > (begin (do-something x y) ...)) > > (macro (1 2 3) (4 5)) > (newline) > > (define-syntax (macro2 stx) > (syntax-parse stx > [(_macro2 (x ...) ys) > (with-syntax ([ooo #'(... ...)]) >#'(begin >(let () > (define-syntax-rule (inner (y ooo)) >(begin (do-something x y) ooo)) > (inner ys)) >...))])) > > (macro2 (1 2 3) (4 5)) > > > 2017-09-01 15:48 GMT+02:00 Jos Koot : > >> How about: >> >> (define-syntax (macro stx) >> (syntax-case stx () >> [(_ (var1 ...) (var2 ...)) >> #`(begin >> #,@(for*/list ((v1 (in-list (syntax->list #'(var1 ... >>(v2 (in-list (syntax->list #'(var2 ...) >> #`(do-something #,v1 #,v2)))])) >> >> Jos >> >> -Original Message- >> From: racket-users@googlegroups.com [mailto:racket-users@googlegroups.com] >> On Behalf Of Sam Waxman >> Sent: viernes, 01 de septiembre de 2017 11:37 >> To: Racket Users >> Subject: [racket-users] Mapping over pattern variables >> >> Lets say I have a macro >> >> (define-syntax (macro stx) >> (syntax-parse stx >> [(_ (var1 ...) (var 2 ...)) >> #'(begin >> (begin >>(do-something (#freeze var1) var2) >>...) >> ...)])) >> >> and I want to iterate first over var2, and then over var1. So if I type >> >> (macro (1 2 3) (1 2)) >> >> I should get >> >> (begin >> (begin >> (do-something 1 1) >> (do-something 1 2)) >> (begin >> (do-something 2 1) >> (do-something 2 2)) >> (begin >> (do-something 3 1) >> (do-something 3 2))) >> >> What do I put where I currently have "#freeze" to tell the expander that >> I don't want the ... to affect var1? Or do I have to do >> this manually with syntax->list and mapping functions? >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Racket Users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to racket-users+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Racket Users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to racket-users+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > > > -- > -- > Jens Axel Søgaard > > -- -- Jens Axel Søgaard -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Mapping over pattern variables
Two variations: #lang racket (require (for-syntax syntax/parse)) (define (do-something x y) (displayln (list x y))) (define-syntax-rule (macro (x ...) ys) (begin (outer x ys) ...)) (define-syntax-rule (outer x (y ...)) (begin (do-something x y) ...)) (macro (1 2 3) (4 5)) (newline) (define-syntax (macro2 stx) (syntax-parse stx [(_macro2 (x ...) ys) (with-syntax ([ooo #'(... ...)]) #'(begin (let () (define-syntax-rule (inner (y ooo)) (begin (do-something x y) ooo)) (inner ys)) ...))])) (macro2 (1 2 3) (4 5)) 2017-09-01 15:48 GMT+02:00 Jos Koot: > How about: > > (define-syntax (macro stx) > (syntax-case stx () > [(_ (var1 ...) (var2 ...)) > #`(begin > #,@(for*/list ((v1 (in-list (syntax->list #'(var1 ... >(v2 (in-list (syntax->list #'(var2 ...) > #`(do-something #,v1 #,v2)))])) > > Jos > > -Original Message- > From: racket-users@googlegroups.com [mailto:racket-users@googlegroups.com] > On Behalf Of Sam Waxman > Sent: viernes, 01 de septiembre de 2017 11:37 > To: Racket Users > Subject: [racket-users] Mapping over pattern variables > > Lets say I have a macro > > (define-syntax (macro stx) > (syntax-parse stx > [(_ (var1 ...) (var 2 ...)) > #'(begin > (begin >(do-something (#freeze var1) var2) >...) > ...)])) > > and I want to iterate first over var2, and then over var1. So if I type > > (macro (1 2 3) (1 2)) > > I should get > > (begin > (begin > (do-something 1 1) > (do-something 1 2)) > (begin > (do-something 2 1) > (do-something 2 2)) > (begin > (do-something 3 1) > (do-something 3 2))) > > What do I put where I currently have "#freeze" to tell the expander that I > don't want the ... to affect var1? Or do I have to do > this manually with syntax->list and mapping functions? > > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- -- Jens Axel Søgaard -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
RE: [racket-users] Mapping over pattern variables
How about: (define-syntax (macro stx) (syntax-case stx () [(_ (var1 ...) (var2 ...)) #`(begin #,@(for*/list ((v1 (in-list (syntax->list #'(var1 ... (v2 (in-list (syntax->list #'(var2 ...) #`(do-something #,v1 #,v2)))])) Jos -Original Message- From: racket-users@googlegroups.com [mailto:racket-users@googlegroups.com] On Behalf Of Sam Waxman Sent: viernes, 01 de septiembre de 2017 11:37 To: Racket Users Subject: [racket-users] Mapping over pattern variables Lets say I have a macro (define-syntax (macro stx) (syntax-parse stx [(_ (var1 ...) (var 2 ...)) #'(begin (begin (do-something (#freeze var1) var2) ...) ...)])) and I want to iterate first over var2, and then over var1. So if I type (macro (1 2 3) (1 2)) I should get (begin (begin (do-something 1 1) (do-something 1 2)) (begin (do-something 2 1) (do-something 2 2)) (begin (do-something 3 1) (do-something 3 2))) What do I put where I currently have "#freeze" to tell the expander that I don't want the ... to affect var1? Or do I have to do this manually with syntax->list and mapping functions? -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Mapping over pattern variables
On Fri, Sep 1, 2017 at 5:36 AM, Sam Waxmanwrote: > Lets say I have a macro > > (define-syntax (macro stx) > (syntax-parse stx > [(_ (var1 ...) (var 2 ...)) > #'(begin > (begin >(do-something (#freeze var1) var2) >...) > ...)])) > > and I want to iterate first over var2, and then over var1. So if I type > > (macro (1 2 3) (1 2)) > > I should get > > (begin > (begin > (do-something 1 1) > (do-something 1 2)) > (begin > (do-something 2 1) > (do-something 2 2)) > (begin > (do-something 3 1) > (do-something 3 2))) > > What do I put where I currently have "#freeze" to tell the expander that I > don't want the ... to affect var1? Or do I have to do this manually with > syntax->list and mapping functions? > Assuming the 'begin' statements aren't essential, you could make your macro generate a 'for' clause: (for/list ((i '(1 2 3)) #:when #t (j '(1 2))) (list i j)) Result: '((1 1) (1 2) (2 1) (2 2) (3 1) (3 2)) > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Unit tests for a #lang implementation
Matthew, > If you'd like the test namespace and the test-driving module to share > the instance of the module that defines `document` (so that they'll > agree on the data structure), you can use `namespace-attach-module` to > attach the test-driving module's instance to a newly created namespace. Thanks again for a valuable pointer to the Racket documentation! This works well for modules that my test module requires directly, as in your example. I haven't been able to get any useful results for modules that are required indirectly (i.e. your module "a.rkt" requiring "c.rkt" and re-providing a struct from there). Depending on which combination of modules I run namespace-attach-module on, I either get my initial error or another one: amespace-attach-module: a different module with the same name is already in the destination namespace ; module name: "/Applications/Racket v6.10/collects/racket/pretty.rkt" None of my code refers to pretty.rkt. I think I will simply give up at this point. Compared to depending on complex stuff that I don't understand, nor want to understand, a separate testing shell script seems like the lesser evil. Thanks again, Konrad. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Mapping over pattern variables
Lets say I have a macro (define-syntax (macro stx) (syntax-parse stx [(_ (var1 ...) (var 2 ...)) #'(begin (begin (do-something (#freeze var1) var2) ...) ...)])) and I want to iterate first over var2, and then over var1. So if I type (macro (1 2 3) (1 2)) I should get (begin (begin (do-something 1 1) (do-something 1 2)) (begin (do-something 2 1) (do-something 2 2)) (begin (do-something 3 1) (do-something 3 2))) What do I put where I currently have "#freeze" to tell the expander that I don't want the ... to affect var1? Or do I have to do this manually with syntax->list and mapping functions? -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.