Re: [racket-dev] split-for-body from syntax/for-body
>> So is the reason why #:when and #:unless can't be used the same way >> because there already exist when and unless forms? > > Are you looking for an equivalent of C's "continue" statement? I could > imagine clauses for skipping to the next iteration using the keyword > #:continue or #:next, though I have no idea if the existing loop > architecture would easily accommodate them. I don't think calling them > #:when or #:unless makes sense outside the for clauses. Hmm, I take back my previous question, which didn't make sense (because it may result in unwanted voids). Now I'm thinking #:when and #:unless *should* be allowed in the body, for the exact reasons why #:final and #:break are allowed. But presumably there is a reason they were left out? It would be similar to C's continue, but the names should probably be the same, since they do the same thing as clause-based #:when/unless? Yes, I think the current architecture would support this change easily since it's accumulator-based. If a #:when/unless condition is true, you just call the loop with the old accumulators. I can put it in if there is agreement. > >> >> >> > Carl Eastlund >> >> > >> >> > >> >> > On Fri, Sep 6, 2013 at 2:31 PM, Stephen Chang >> >> > wrote: >> >> >> >> >> >> > "Among the bodys, besides stopping the iteration and preventing >> >> >> > later >> >> >> > body evaluations, a #:break guard-expr or #:final guard-expr >> >> >> > clause >> >> >> > starts a >> >> >> > new internal-definition context." >> >> >> >> >> >> I had the same thought process as Carl. I now understand the >> >> >> behavior >> >> >> but I don't understand why it's needed? It seems kind of arbitrary >> >> >> since no other form allows multiple internal def contexts in the >> >> >> body >> >> >> like this. Is there a practical example? >> >> >> >> >> >> On Fri, Sep 6, 2013 at 12:58 PM, Carl Eastlund >> >> >> wrote: >> >> >> > Okay, I see what's going on here. It's very subtle though, and >> >> >> > probably >> >> >> > deserves some explanation in split-for-body's documentation. >> >> >> > >> >> >> > My first thought on seeing my non-fix version break here is that I >> >> >> > can >> >> >> > make >> >> >> > split-for-body break the same way. The problem is that my non-fix >> >> >> > separates >> >> >> > the definition of fish? from the definitions of red? and blue?, >> >> >> > which >> >> >> > it >> >> >> > depends on. I can make split-for-body separate them the same way, >> >> >> > by >> >> >> > putting a #:break or #:final clause in between the definition of >> >> >> > fish? >> >> >> > and >> >> >> > the begin form. >> >> >> > >> >> >> > The problem with doing so is a subtle point about for loops that >> >> >> > is >> >> >> > only >> >> >> > mentioned in the last sentence of the last paragraph of the >> >> >> > documentation of >> >> >> > for itself: >> >> >> > >> >> >> > "Among the bodys, besides stopping the iteration and preventing >> >> >> > later >> >> >> > body >> >> >> > evaluations, a #:break guard-expr or #:final guard-expr clause >> >> >> > starts >> >> >> > a >> >> >> > new >> >> >> > internal-definition context." >> >> >> > >> >> >> > So that's what split-for-body is preserving, the boundaries >> >> >> > between >> >> >> > internal >> >> >> > definition contexts. That's not at all what I had expected it was >> >> >> > doing; I >> >> >> > had no idea the body of a for loop constituted multiple such >> >> >> > contexts. >> >> >> > >> >> >> > Anyway, thanks for the clarification, I now understand why >> >> >> > abstractions >> >> >> > over >> >> >> > for loops need to use split-for-body. >> >> >> > >> >> >> > Carl Eastlund >> >> >> > >> >> >> > >> >> >> > On Fri, Sep 6, 2013 at 12:38 PM, Matthew Flatt >> >> >> > >> >> >> > wrote: >> >> >> >> >> >> >> >> Sorry that I forgot to add the `let` while turning the code you >> >> >> >> sent >> >> >> >> into a full example. Here's another try. >> >> >> >> >> >> >> >> #lang racket/base >> >> >> >> (require (for-syntax racket/base >> >> >> >> syntax/parse >> >> >> >> syntax/for-body)) >> >> >> >> >> >> >> >> (define-syntax (for/print/good stx) >> >> >> >> (syntax-parse stx >> >> >> >> [(_ clauses . body) >> >> >> >> (with-syntax ([([pre ...] [post ...]) (split-for-body stx >> >> >> >> #'body)]) >> >> >> >>(syntax >> >> >> >> (for clauses >> >> >> >> pre ... >> >> >> >> (printf "~v\n" (let () post ...)])) >> >> >> >> >> >> >> >> (define-syntax-rule (for/print/fixed/not clauses pre ... result) >> >> >> >> (for clauses >> >> >> >> pre ... >> >> >> >> (printf "~v\n" (let () result >> >> >> >> >> >> >> >> (for/print/fixed/not ([i 1]) >> >> >> >> (define (fish? v) (or (red? v) (blue? v))) >> >> >> >> (begin >> >> >> >> (define (red? v) (eq? v 'red)) >> >> >> >> (define (blue? v) (eq? v 'blue)) >> >> >> >> (fish? i))) >> >> >> >> >> >> >> >> At Fri, 6 Sep 2013 12:30:17 -0400, Carl Eastlund
Re: [racket-dev] [plt] Push #27446: master branch updated
Typed Racket has to expand into code that registers the type of each module-top-level identifier in the global environment so that other modules can find the types to typecheck with. For example, this program: #lang typed/racket (provide x) (define: x : Integer 1) expands into (greatly simplified): #lang ... (#%provide x) (begin-for-syntax (declare #'x Integer-rep)) (define-values (x) 1) but what is `Integer-rep`? It needs to be an expression that _constructs_ the internal Typed Racket representation of the `Integer` type. Previously, that looked something like this: (make-Union (sort (list Negative-Fixnum-rep Positive-Fixnum-rep ...))) and so on and so forth for the components, all the way down to base types. You can imagine how this gets quite large, especially for large types. However, this is wasteful, because every Typed Racket program, at type checking time, defines a constant that's the representation of the `Integer` type, right here [1]. So instead of serializing an expression that constructs the same thing as `-Int`, we can just *reference* `-Int` in the expanded code. To make that possible, Typed Racket now builds a hash table [2] mapping types (really, their representations) to identifiers that denote those types. Then the serializer just consults this table [3]. It turns out that base types (but no others) already used basically this mechanism, by storing the identifier *in* the type representation. But that's now obsolete, and thus was removed in my subsequent commit. As a result, the type serialization is much smaller. [1] https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/types/numeric-tower.rkt#L107 [2] https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/types/base-abbrev.rkt#L23 [3] https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/env/init-envs.rkt#L51 On Sat, Sep 7, 2013 at 3:20 PM, Neil Toronto wrote: > On 09/06/2013 04:14 PM, sa...@racket-lang.org wrote: >> >> 56b372c Sam Tobin-Hochstadt 2013-09-06 14:22 >> : >> | Remember types that are defined, and use them in serialization. >> | >> | This extends a facility already available for base types, >> | making that facility no longer strictly needed. >> | >> | Shrinks the zo size for the `math` package by almost 1MB. >> : >>M .../typed-racket/env/init-envs.rkt| 1 + >>M .../typed-racket/typecheck/def-export.rkt | 7 +- >>M .../typed-racket/typecheck/tc-toplevel.rkt| 31 +++--- >>M .../typed-racket/types/abbrev.rkt | 36 +++ >>M .../typed-racket/types/base-abbrev.rkt| 12 ++- >>M .../typed-racket/types/numeric-tower.rkt | 108 >> +-- > > > Would you mind explaining this a little more? It sounds interesting, and the > commit almost has my name in it. :) > > Neil ⊥ > _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] split-for-body from syntax/for-body
On Fri, Sep 6, 2013 at 2:58 PM, Stephen Chang wrote: > > It's useful when the condition for loop termination and the value of the > > loop body both depend on some derived computation from the sequence > > elements: > > > > (for/list ([x (in-stream S)]) > > (define y (f x)) > > #:break (g? y) > > (h y)) > > Ok I see, thanks. It does make things easier to read when the break > expression becomes too large to fit on one line. So is the reason why > #:when and #:unless can't be used the same way because there already > exist when and unless forms? > Are you looking for an equivalent of C's "continue" statement? I could imagine clauses for skipping to the next iteration using the keyword #:continue or #:next, though I have no idea if the existing loop architecture would easily accommodate them. I don't think calling them #:when or #:unless makes sense outside the for clauses. > >> > Carl Eastlund > >> > > >> > > >> > On Fri, Sep 6, 2013 at 2:31 PM, Stephen Chang > >> > wrote: > >> >> > >> >> > "Among the bodys, besides stopping the iteration and preventing > later > >> >> > body evaluations, a #:break guard-expr or #:final guard-expr clause > >> >> > starts a > >> >> > new internal-definition context." > >> >> > >> >> I had the same thought process as Carl. I now understand the behavior > >> >> but I don't understand why it's needed? It seems kind of arbitrary > >> >> since no other form allows multiple internal def contexts in the body > >> >> like this. Is there a practical example? > >> >> > >> >> On Fri, Sep 6, 2013 at 12:58 PM, Carl Eastlund > wrote: > >> >> > Okay, I see what's going on here. It's very subtle though, and > >> >> > probably > >> >> > deserves some explanation in split-for-body's documentation. > >> >> > > >> >> > My first thought on seeing my non-fix version break here is that I > >> >> > can > >> >> > make > >> >> > split-for-body break the same way. The problem is that my non-fix > >> >> > separates > >> >> > the definition of fish? from the definitions of red? and blue?, > which > >> >> > it > >> >> > depends on. I can make split-for-body separate them the same way, > by > >> >> > putting a #:break or #:final clause in between the definition of > >> >> > fish? > >> >> > and > >> >> > the begin form. > >> >> > > >> >> > The problem with doing so is a subtle point about for loops that is > >> >> > only > >> >> > mentioned in the last sentence of the last paragraph of the > >> >> > documentation of > >> >> > for itself: > >> >> > > >> >> > "Among the bodys, besides stopping the iteration and preventing > >> >> > later > >> >> > body > >> >> > evaluations, a #:break guard-expr or #:final guard-expr clause > starts > >> >> > a > >> >> > new > >> >> > internal-definition context." > >> >> > > >> >> > So that's what split-for-body is preserving, the boundaries between > >> >> > internal > >> >> > definition contexts. That's not at all what I had expected it was > >> >> > doing; I > >> >> > had no idea the body of a for loop constituted multiple such > >> >> > contexts. > >> >> > > >> >> > Anyway, thanks for the clarification, I now understand why > >> >> > abstractions > >> >> > over > >> >> > for loops need to use split-for-body. > >> >> > > >> >> > Carl Eastlund > >> >> > > >> >> > > >> >> > On Fri, Sep 6, 2013 at 12:38 PM, Matthew Flatt > > >> >> > wrote: > >> >> >> > >> >> >> Sorry that I forgot to add the `let` while turning the code you > sent > >> >> >> into a full example. Here's another try. > >> >> >> > >> >> >> #lang racket/base > >> >> >> (require (for-syntax racket/base > >> >> >> syntax/parse > >> >> >> syntax/for-body)) > >> >> >> > >> >> >> (define-syntax (for/print/good stx) > >> >> >> (syntax-parse stx > >> >> >> [(_ clauses . body) > >> >> >> (with-syntax ([([pre ...] [post ...]) (split-for-body stx > >> >> >> #'body)]) > >> >> >>(syntax > >> >> >> (for clauses > >> >> >> pre ... > >> >> >> (printf "~v\n" (let () post ...)])) > >> >> >> > >> >> >> (define-syntax-rule (for/print/fixed/not clauses pre ... result) > >> >> >> (for clauses > >> >> >> pre ... > >> >> >> (printf "~v\n" (let () result > >> >> >> > >> >> >> (for/print/fixed/not ([i 1]) > >> >> >> (define (fish? v) (or (red? v) (blue? v))) > >> >> >> (begin > >> >> >> (define (red? v) (eq? v 'red)) > >> >> >> (define (blue? v) (eq? v 'blue)) > >> >> >> (fish? i))) > >> >> >> > >> >> >> At Fri, 6 Sep 2013 12:30:17 -0400, Carl Eastlund wrote: > >> >> >> > You're proving that (let () ...) is necessary, which I have > >> >> >> > explicitly > >> >> >> > agreed with since the original email, but you have not yet > >> >> >> > demonstrated > >> >> >> > that split-for-body is necessary. Here is the fix I have > >> >> >> > described > >> >> >> > twice > >> >> >> > already, now explicitly put into the define-syntax-rule > solution: > >> >> >> > > >> >> >> > (define-syntax-rule (for/pr
Re: [racket-dev] net/http-client
On Wed, Sep 4, 2013 at 11:03 AM, Jay McCarthy wrote: > On Wed, Aug 28, 2013 at 3:30 PM, Greg Hendershott > wrote: >> >> This looks great!! >> >> A couple suggestions: >> >> 1. Support for "Expect: 100-continue" request headers would be >> helpful, and I think not too messy to add. >> >> The big use case I'm aware of is Amazon S3. If you make a PUT or POST >> request, it might need to redirect you to another URI (outage, >> balancing, whatever reason). Expecting and handling 100-continue lets >> you avoid transmitting potentially large amount of data that would be >> discarded, and you have to send it all over again in the request to >> the redirect URI. For (say) a 1 GB upload to S3, this matters. >> Although I don't know for sure if other upload-ish web APIs offer >> same, I'd guess some do as this is the use case for 100-continue >> generally. >> >> How I implemented this in my HTTP package was to have a >> `start-request` function that sends the request line and headers, >> peeks the response status line, then returns a `boolean?` whether the >> PUT/POST/PATCH/whatever data should be transmitted. [1] >> >> I think your `http-conn-send!` could do similar? > > > Do you think it is appropriate to expect the http-client user to put in the > "Expect: 100-continue" or better to always send it if there is a data > component? Great question. I took the approach of requiring the client to supply it if they care. Instead supplying it always/automatically does seem neat. But safe? Reading http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html I'm a little nervous about this section: A server that does not understand or is unable to comply with any of the expectation values in the Expect field of a request MUST respond with appropriate error status. The server MUST respond with a 417 (Expectation Failed) status if any of the expectations cannot be met or, if there are other problems with the request, some other 4xx status. This suggests a scenario where a server might error a request solely because of the presence of an "Expect: 100-continue" header. That doesn't strike me as reasonable behavior, but I could imagine some server doing it. So I suppose best to default to supplying it automatically, but provide a way for the client to disable that. How to specify disabling? With headers like "Server:" you have a default but let the user's supplied headers override. But supplying "Expect: " (i.e. "Expect: ") would feel weird, to a user. And actually sending that -- if it feels weird to a server causing it to error, well that's the whole thing we're trying to avoid, see above. So (tl;dr) perhaps add an optional function parameter that defaults to #t, e.g. `[expect-100-continue? #t]` ? > >> >> 2. Support for "Content-Encoding" response headers would also be helpful. >> >> Using the same make-pipe approach as you're doing with chunked >> transfer encoding. [2] Maybe this is mission creep: For HTTP 1.1. you >> _must_ support Transfer-Encoding: chunked, whereas Content-Encoding is >> just optional. However it's a good option; using compression can >> really help out on time as well as bandwidth charges. > > > I just pushed support for this. Nice, thanks! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #27454: master branch updated
Is the change to the native-pkgs sha1 intentional? Sam On Sep 8, 2013 3:04 AM, wrote: > stchang has updated `master' from 672e909880 to 7eaee796e1. > http://git.racket-lang.org/plt/672e909880..7eaee796e1 > > =[ 3 Commits ]== > Directory summary: > 92.8% pkgs/racket-pkgs/racket-test/tests/racket/ > > ~~ > > 060ffeb Stephen Chang 2013-09-08 01:48 > : > | add for/X tests for multi-loop break > : > M native-pkgs| 2 +- > M pkgs/racket-pkgs/racket-test/tests/racket/for.rktl | 6 ++ > > ~~ > > b685746 Stephen Chang 2013-09-08 02:00 > : > | add for/X tests for outer-loop #:final condition > | > | - make sure innermost loop is executed only one more time > : > M pkgs/racket-pkgs/racket-test/tests/racket/for.rktl | 6 ++ > > ~~ > > 7eaee79 Stephen Chang 2013-09-08 03:03 > : > | add more for/X tests > | > | - #:break and #:final in body with exprs in between > | - both #:break and #:final > | - skipped #:final > : > M .../racket-pkgs/racket-test/tests/racket/for.rktl | 25 > > > =[ Overall Diff ]=== > > native-pkgs > ~~~ > --- OLD/native-pkgs > +++ NEW/native-pkgs > @@ -1 +1 @@ > -Subproject commit 5f391155f276da25df85081cf8c80a9760a404b0 > +Subproject commit f367c0c4b05b91401d68b0180b416d616b31720d > > pkgs/racket-pkgs/racket-test/tests/racket/for.rktl > ~~ > --- OLD/pkgs/racket-pkgs/racket-test/tests/racket/for.rktl > +++ NEW/pkgs/racket-pkgs/racket-test/tests/racket/for.rktl > @@ -383,4 +383,41 @@ > (define-sequence-syntax in-X* (lambda () #'in-X) (lambda (stx) > #f)) > (for/list ([x (in-X* #:x '(1 2 3))]) x))) > > + > +;; extra tests for #:break and #:final > +(test '((0 0) (0 1) (1 0) (1 1)) 'multi-level-break > + (for*/list ([i 4] [j 2] #:break (= i 2)) (list i j))) > +(test '((1 0 0) (1 0 1) (1 1 0) (1 1 1)) 'multi-level-break > + (for/list ([i 5] #:when (odd? i) [j 2] #:when #t [k 2] #:break (= i > 3)) > +(list i j k))) > +(test '((0 0) (0 1) (1 0) (1 1) (2 0)) 'outer-loop-final > + (for*/list ([i 4][j 2] #:final (= i 2)) (list i j))) > +(test '((0 0) (0 1) (1 0) (1 1) (2 0)) 'outer-loop-final > + (for/list ([i 4] #:final (= i 2) [j 2]) (list i j))) > + > +(test '((0 0) (0 1) (1 0) (1 1)) 'break-and-final > + (for*/list ([i 4][j 2] #:final (= i 2) #:break (= i 2)) (list i j))) > + > +(test '((0 0) (0 1) (1 0) (1 1)) 'break-and-final > + (for*/list ([i 4][j 2] #:break (= i 2) #:final (= i 2)) (list i j))) > + > +(test '((0 1) (1 1)) 'skipped-final > + (for*/list ([i 4][j 2] #:final (= i 2) #:unless (= j 0)) (list i > j))) > + > +;; check #:break and #:final in body with exprs in between > +(test (list 0 1) 'nested-body-break > + (for/list ([i 4]) (define j (add1 i)) #:break (= j 3) i)) > +(test (list 0 1 2) 'nested-body-final > + (for/list ([i 4]) (define j (add1 i)) #:final (= j 3) i)) > +(test '((0 0) (0 1) (1 0) (1 1)) 'nested-body-break-and-final > + (for*/list ([i 4][j 2]) > +(define k i) #:final (= k 2) > +(define m i) #:break (= m 2) > +(list i j))) > +(test '((0 0) (0 1) (1 0) (1 1)) 'nested-body-break-and-final > + (for*/list ([i 4][j 2]) > +(define m i) #:break (= m 2) > +(define k i) #:final (= k 2) > +(list i j))) > + > (report-errs) > _ Racket Developers list: http://lists.racket-lang.org/dev