At RacketCon 2018’s
office
hours, David Thrane
Christiansen talked about “normalization by evaluation” as a
prelude to his “Implementing Dependent Types” session.
In the design he sketched, the normalizer needed help from the
evaluator. I wondered if it was possible to use a standard (oblivious)
evaluator, such as Racket’s normal eval. The answer is no —
but kind of.
I’m rebooting my blog, previously
hosted on Blogspot. I finished
a conversion to Frog some time ago — there weren’t that many posts to
convert, and I was already using Scribble and my now-defunct tool
Scriblogify.
But there was just one thing I wanted to fix about Frog’s Scribble rendering
first. And then there was another thing, and so on, and in the end I wound up
with something different enough to give it a new name.
In Racket 7, the syntax form supports two new template subforms:
~@ (“splice”) splices the result of its subtemplate (which must
produce a syntax list) into the enclosing list template, and
~? (“try”) chooses between alternative subtemplates depending
on whether their pattern variables have “absent” values.
These features originated in syntax/parse/experimental/template:
the template form was like an extended version of syntax, and
?@ and ?? were the splicing forms and the try/else template
forms, respectively. The names were changed to ~@ and ~? to
avoid name collisions with other libraries. In Racket 7, the old
syntax/parse/experimental/template library just exports the new
standard forms under the old names (that is, it exports syntax under
the name template, and so on).
Racket’s macro system gives macros two ways of associating
static (or compile-time) information with a particular
name. One way is to define the name as the static information;
the other is to attach the information to the already-defined
name.
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.
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.
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.
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—with a bit of care—even macros.
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—except that scope is too simple a term for how bindings work
in such contexts. Enclosing binding forms are simpler and cleaner but
weaker; definition forms are more powerful, but have a more
complicated binding structure. Definitions also have the pleasant
property of reducing rightward code drift.
In my
last post, I talked about macros and referential auxiliary
identifiers—what we usually call a macro’s “literals.” Scheme
macro systems only get it half right, though, because while they
compare identifiers using referential equality (i.e., using the
free-identifier=? predicate), they allow literals to refer to
nonexistent bindings. While the comparison is well-defined via the
definition of free-identifier=?, at a higher level the idea
is nonsensical.
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).
Copyright 2006–2020 Ryan Culpepper.
This work is licensed under a
Creative Commons Attribution-ShareAlike 4.0 International License.