Because, I think, for a language to be considered truly general#
Tue, 03 Jun 2003 03:52:46 +0000
Because, I think, for a language to be considered truly general
purpose it must be good for evil baling-wire-and-duct-tape kludges as
well as for beautiful elegant robust well-engineered solutions,
I have (minimal) pleasure in showing you asdf-install.lisp (temporary location).
"Not work-viewable", as they say
Note in passing: the cclan >(foo) and :(download
...) tokens are both deprecated. If you follow these rules, you
can use the new :(package ...) syntax instead.
- The CLiki page name must be the asdf system name, after downcasing
- The package link is either :(package "foo.tar.gz") for
a package in cCLan, or :(package
"full://url/to/host/foo.tar.gz") for a package somewhere else
- There is only one package link per page
- It must point to a gzipped tarball of an ASDF System or close approximation
- The package must be Free according to DFSG
Not only was yesterday's entry almost criminally dull, rereading shows it not#
Wed, 04 Jun 2003 00:24:46 +0000
Not only was yesterday's entry almost criminally dull, rereading shows it not
to have been terribly clear either.
The project here is an automatic download/install tool for SBCL,
along the lines of CPAN.pm. How it works: it looks up cliki pages with the same
name as the package you tell it you want, and it downloads the url
that the :(package ...) link on that page points at. Yes, all the
stuff about deprecated tokens was talking about CLiki markup syntax.
If the url pointed to is relative, it gets merged against the URL for
the cclan dispatcher, so you eventually end up downloading from some
cclan site that you chose earlier.
CL is actually the third language it's written in: it
started life as a shell script, then as all shell scripts over twenty
lines tend to do, turned into a Perl script. After a couple of hours
screwing around with pathnames in Perl, I decided that CL would have
been the better choice after all.
Yesterday, in accordance with the "small tools that do one thing
each" Unix Philosophy, I was executing wget in a subshell to
actually get the file. Due to the way that cliki and cclan are
arranged, this can potentially involve several redirects. Today I
determined that to additionally get the PGP signature file for the
package I'd have to grep the standard output of wget -S
looking for a line (actually, the last of n lines) matching
Location, my "brittle interfaces" meter pegged, and so I decided
it'd be quicker to write a small HTTP client.
Today's version of asdf-install.lisp is in the same place as yesterday's (see? I
told you it was a temporary location) and does approximately as
little as yesterday's, but in a marginally more sane way. Seems to
cope with proxies (tested using the NTL proxy system) but doesn't do
any lind of proxy authentication yet. Nor FTP, which limits it to
cCLan nodes that are available by HTTP.
A word of warning: this represents a software engineering advance
on yesterday's code. It is still not, in absolute terms, anything you
should even briefly entertain the idea of reusing for other purposes:
there are some much better designed network client libraries out
there. The sole purpose of this one is to provide the minimal code
necessary that the user can easily download and install one of them.
OK, it now also checks PGP signatures, which I think makes it#
Wed, 04 Jun 2003 04:19:05 +0000
OK, it now also checks PGP signatures, which I think makes it
sufficiently complicated that any change could just as easily break it
as improve it, so it's time to start using CVS.
Caption competition#
Sun, 08 Jun 2003 21:18:47 +0000
Caption competition
http://www.catb.org/~esr/graphics/raymond007-5.jpg
- 896 - fetchmailrc syntax
shoot tuxedo.org proto anarchist target advocacy there is
foot here fetchall
- "Eric's default emacs binding for leak-microsoft-memo proves more
unwieldy than he was expecting"
For a long time I've been meaning to put the SBCL User Manual on the web#
Mon, 16 Jun 2003 20:36:52 +0000
For a long time I've been meaning to put the SBCL User Manual on the web
somewhere that Google can find it. So, I was quite happy to see that
Xach has done it already.
It's fashionable, I know, when speaking to an RDBMS, to write or use#
Sat, 21 Jun 2003 15:24:20 +0000
It's fashionable, I know, when speaking to an RDBMS, to write or use
an interface that presents an object-oriented view of the database,
typically by mapping table rows onto objects. I make the following
observations mostly off the top of my head.
- Every object 'get' typically involves a select which fetches all
columns, even if you were only going to use one of two of them.
Slightly inefficient.
- It's very tempting to do something like
(remove-if-not #'interesting-p (all-instances 'emp))
to get a list of objects that satisfy some arbitrary interesting-p
criterion. Horrendously inefficient. OK, so don't do that;
encode your selection criterion as SQL. - Following a chain of object references involves multiple database
fetches (if done the simple way) or some probably quite complex
stuff to work out when a join will save time.
(emp-name (emp-manager *me*))
- Unless every field access does a new row fetch (or you have
some kind of database driver that can give you unsolicited
notifications when data changes behind your back) your object is
always potentially slightly out of date w.r.t. the actual database
contents.
- Unless you keep tabs on the objects you create, it's possible to
have two non-EQ objects that refer to the same row. (Insofar as
there's any concept of identity in a relational database
anyway, but assume there's some kind of unique constraint on
the table). This is fine for read-only data, but can be icky when
updating.
- Links between table rows are essentially bi-directional - it's
as easy to find the manager given an employee as it is to find the
employees given the manager. The natural OO model gives each employee
a list to his manager, or each manager a set (a list, vector,
whatever) of employees. Sure, you could do both. See preceding
point, though: you'd better be sure that you know whether
(member me (car (manager-employees (emp-manager me))))
or not.
- If that was a bit weird, modelling inheritance is weirder.
In short, it's slower than doing raw relational lookups, and has
trouble with object identity leading to possible data consistency
issues. So what's the actual advantage of making the table
rows look like objects? Presumably the theory is that table rows
correspond to domain objects, and therefore we should be able to hang
methods on them that do useful operations. It's my conjecture, based
on looking at an UncommonSQL application I have here in front of me
(bits of which are anything up to three or four years old), that
that's not in general true: domain objects are bigger. In relational
terms, there's a 1:n relation between an invoice and an invoiceline,
but in domain terms we say that the lines are part of the invoice.
This is probably why 'invoiceline' is such a poor name: if it was a
useful domain concept, the domain experts would have a name for it.
So, for a lot of less, uh, "pivotal" (sorry) tables, the only
methods they end up with are boring little things like "print this
line as HTML, or PDF, or something". Even "delete this line", which
you might suggest, is actually "remove this line from the invoice".
And then you find (or at least, I found) that given n different
circumstances where you want to print an object, in at least
n-2 cases you want to print different columns, or you're
printing HTML and want the item description to be a link to some
place, or there is some important reason that you need to embed a hunk
of javascript into the middle of the output. So perhaps you introduce
a (print-instance o :short) and (print-instance o
:full), and then suddenly you find there are a bunch of other
cases where you also need (print-instance o
:link-email-address) or (print-instance o
:two-digit-year), and each of these is only ever called once.
And if you put all the methods into the same file so you stand a
chance of finding out what each of them does and reusing them for new
output reports instead of creating new ones, then you find
that you don't dare change any of them when your format requirement
changes, because you don't know what other page or reports are using
it. So, wouldn't it make more sense to define the formatting at the
point where you need it?
In other news, I'm attempting to train myself to use C-delete to
delete words, because in psgml mode C-M-k doesn't.