When implementing a wire protocol, one occasionally needs to know something about the wires. This blog post is the story of how the placement of a call to flush-output caused a factor-of-20 variation in performance.
one racketeer
Ryan Culpepper on macros, functional programming, and programming language research
Friday, March 16, 2012
Thursday, February 09, 2012
unprepared queries vs statement caching
Racket’s db library supports parameterized queries where the SQL is given as a string (that is, unprepared):
(query-list c "SELECT field1 FROM table WHERE field2 = ?" 17)
This is handled by an implicit call to prepare, which turns the string into a prepared statement; the prepared statement is then executed with the arguments.
The problem with this approach is that it involves two trips to the server: one to prepare and one to execute. One trip would be better. In this post I discuss two techniques for eliminating extraneous server trips. I’ve recently added one of them to Racket; the other turns out to be problematic.
Monday, October 31, 2011
in praise of PostgreSQL arrays
I just added support for PostgreSQL arrays to the db library. While there are some uses of arrays that are iffy from a database design standpoint, there’s one use that weighs overwhelmingly in their favor: avoiding dynamic generation of SQL IN comparisons.
Thursday, October 27, 2011
Sunday, October 16, 2011
lazy module loading
The Racket module system is good at managing dependencies. When you require a module, you ensure that that module is initialized before your code runs, and when the other module changes, the compiler will notice and recompile your module too. Racket even stratifies dependencies according to phase levels so you can use some modules in your macro implementations and other modules in your run-time code and the expander/compiler/linker knows what you want when. It keeps track and makes sure that everything is loaded and available when it’s supposed to be.
But sometimes you want to manage dependencies yourself. This post
is about how to lazily load the implementations of functions
and—
Tuesday, September 27, 2011
definitions vs enclosing binding forms
There are two kinds of binding forms in Racket: definitions and enclosing binding forms. The scope of a binding introduced by an enclosing binding form is entirely evident: it’s one (or more) of the form’s sub-terms. For example, in
the scope of the var bindings is body. In
contrast, the scope of a definition is determined by its context: the
enclosing lambda body, for example, or the enclosing
module—
Friday, September 09, 2011
syntax-parse and literals
In
my
last post, I talked about macros and referential auxiliary
identifiers—
In contrast, syntax-parse requires that every literal refer to some binding. (I’ll sometimes refer to this requirement as the is-bound property for short.) This requirement is problematic in a different way. Specifically, this property cannot be checked statically (that is, when the syntax-parse expression containing the literal is compiled).
That might strike you as bizarre or unlikely. After all, you can easily imagine checking that a syntax-rules macro, say, satisfies the is-bound property. But in Racket, not every macro uses syntax-rules, and—more importantly—not every bit of syntax-analyzing code is a macro. And both of these facts have to do with phases.