[racket] Cleaner way to work with gzipped data?

From: JP Verkamp (racket at jverkamp.com)
Date: Tue Aug 6 19:34:58 EDT 2013

> 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130806/2cbc3411/attachment-0001.html>

Posted on the users mailing list.