[racket-users] web-server - stream file uploads? [was ... servlet performance ...]

2017-09-01 Thread George Neuner
On Fri, 1 Sep 2017 14:38:21 -0400, Neil Van Dyke
 wrote:

> ... *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

2017-09-01 Thread Neil Van Dyke
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

2017-09-01 Thread Neil Van Dyke

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

2017-09-01 Thread Jack Firth
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

2017-09-01 Thread dbohdan
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

2017-09-01 Thread Philip McGrath
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øgaard 
wrote:

> 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

2017-09-01 Thread Jens Axel Søgaard
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

2017-09-01 Thread 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

-- 
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

2017-09-01 Thread 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.


Re: [racket-users] Mapping over pattern variables

2017-09-01 Thread David Storrs
On Fri, Sep 1, 2017 at 5:36 AM, Sam Waxman  wrote:

> 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

2017-09-01 Thread Konrad Hinsen
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

2017-09-01 Thread Sam Waxman
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.