I want to share two ideas based on my experience so far with the web libraries. This isn't cutting edge CS. It's just some practical stuff about pain points, about how to make it more consistent both "horizontally" and "vertically", so what you learn starting in one quadrant is applicable in the other three.
[1] Horizontally. If you start learning the client side, net/url, very little of what you learn is applicable to the server side. In fact it's often the opposite. Client is strings, but server is bytes. Client has one approach to HTTP headers, server has another. The psychic whiplash is particularly bad if you're switching back and forth. (I recognize this is probably the result of two people or teams making a big contribution at different stages, and they each deserve my appreciation -- thanks sincerely for what you've done!) [2] Vertically. xexprs are a great way to deal with HTTP entities: (tag (attributes) body), nested arbitrarily deeply, quasiquotes, all that good stuff. But why just entities? HTTP messages have the same structure, if you consider HTTP headers to be attribute lists for the entity body. Requests are (method (headers) entity). And responses are let's say (response (headers) entity). It would be great to bundle it all up as one xexpr: (method (headers) entity-xexpr). Now the entire HTTP message is simply an xexpr, whose entity is in turn an xexpr. Now everything you learn about using xexprs, you can apply top to bottom and left to right. I imagine many people on this list could whip up an xexpr-http.rkt module pretty quickly, including some functions to get at xexpr parts, and four functions like send-request and receive-response for the client, and receive-request and send-response for the server, all consuming and producing xexprs. As well as helper functions to read and write entities, automatically transforming common content-types like text/html, application/xml, application/x-www-form-urlencoded to/from bytes. It also helps if you allow these xexprs to have as its body a procedure (which isn't strictly xexpr? today). So you can do incremental, "callback" style requests or responses: `(response ([Status "200" "OK"]) ,(lambda (out) ... a callback ala make/response-incremental )) -- or --- `(put ([ ... ]) ,(lambda (out) ... )) Of course there's a point where doing TOO much with lists instead of structs becomes unwieldy. But maybe it's worth pushing it just a bit, for the sake of xexpr bennies. Does anyone else see value in this kind of approach? Is this something where it's considered OK for everyone who wants it, to code it up themselves? (Have all of you in fact already done this, had this supposed epiphany and graduated beyond it years ago? :) ) Or is worth me putting something like this on GitHub or Planet? Is it even something to consider for Racket itself someday, considering how more consistency could make Racket even more appealing for web dev? _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users