> I had exactly the same confusion back when I first tried it. Your > example is really helpful. Could it be added to the docs for make-pipe > and/or g(un)zip-through-ports?
Go for it. I think that's one of the few problems I tend to have with Racket's documentation is a lack of examples. Function signatures and descriptions are all well and good, but it's not always clear how to get to that point. 1. I notice that with-gzip and with-gunzip are identical except for > the function they call. You could parameterize that away: Replace both > with a single `with-pipe` function that takes any xxx-through-ports > style function (input-port? output-port? . -> . any) as an argument. > [1] > > Because the bulk of the code is about using make-pipe with any such > "converter" function; it doesn't care which. And this pattern of using > make-pipe could easily apply to functions like > transfer-{encoding|decoding}-through-ports and > content-{encoding|decoding}-through-ports for working with HTTP, and > other transforms. Even the identity function for this, `copy-ports`. > Definitely. Primarily I didn't do it since I really only need with-gunzipfor my work, with-gzip was mostly because it was easy to copy/paste. The input is always several orders of magnitude larger than the output, so less point in gzipping it. > 2. There's a lot of thunking going on. On the plus side, traditional > things like with-input-from-file use thunks, so it's consistent with > that. On the other other hand a macro could simplify that so users > don't need to write (lambda () body...) or (thunk body...), they just > write body... directly. > Yup. And that's one of the uglier parts of the code with lots of rightward drift going on. You're right on why I did it though, I wanted it to fit in with the rest of my code. I tend to use with-* rather than opening and closing things myself. In my own code, I've already written exactly that macro though as a wrapper over with-g(un)zip. > [1]: Yeah, it's awkward that gzip-through-ports takes those 2 extra > arguments for filename and time -- it's not just (input-port? > output-port? . -> . any) like the general `make-pipe` wants. But you > could pass either of the following to `make-pipe`: > (lambda (in out) (gzip-through-ports in out #f 0)) > (curryr gzip-through-ports #f 0) I used #f and (current-seconds), but fair point. curry / curryr are nice! Yet another set of things built into Racket that I'd never thought to look for--I would have used the lambda example.
____________________ Racket Users list: http://lists.racket-lang.org/users