diary at Telent Netowrks

Hot property#

Wed, 02 Feb 2005 10:45:33 +0000

Hot property

From: Daniel Barlow <dan@telent.net>
Subject: [OxLUG] GPG key revocation

For anyone who'd signed my GPG key, please be aware that my laptop was stolen at the weekend, so don't trust it any more. The revocation cert below has been sent to the keyservers.

-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.2.5 (GNU/Linux) Comment: A revocation certificate should follow

iHAEIBECADAFAkIAkncpHQJsYXB0b3AgY29udGFpbmluZyBzZWNyZXQga2V5IHdh cyBzdG9sZW4ACgkQHDK5ZnWQiRP18QCfZNMnZyOzdKon3mRKjt6EBn8WpwEAniE/ 9qsy51ZzLlHbFyKellFpMas1 =U0GC -----END PGP PUBLIC KEY BLOCK-----

For information, I claim that my new key is

:; gpg --fingerprint 1297D4B5 gpg: NOTE: old default options file `/home/dan/.gnupg/options' ignored pub 1024D/1297D4B5 2005-02-02 Daniel Barlow <dan@telent.net> Key fingerprint = 13D7 02AD 8665 27E0 8F71 5326 776F D7C0 1297 D4B5 sub 2048g/DE0A0FD9 2005-02-02 [expires: 2010-02-01]

but of course I don't expect you to believe that without the whole face-to-face authentication hassle, so ... [...]

If you see me, feel free to ask for a copy of my fingerprint

There has also been some AMD64/pthreads progress, btw#

Wed, 02 Feb 2005 10:53:05 +0000

There has also been some AMD64/pthreads progress, btw. It now gets as far as creating a core, and dies early in cold-init with some `4 is not a list' error that I haven't fully figured out yet.


Mon, 07 Feb 2005 11:50:14 +0000

MORE PTHREADS. sbcl-devel subscribers will already have seen the current state - it appears to work superficially but there are still holes. Most obviously right now, there's some evil recursive bustup in internal-error support, so any attempt to run an undefined function will cause SBCL to come to a short and sticky end.

The previous `4 is not a list' was caused by a literal 4 that should have been an 8 - or probably even an n-word-bytes, and then we found that assembly trampolines must be 8 byte aligned so that their addresses look like fixnums to the GC.


Tue, 08 Feb 2005 00:38:33 +0000

NO MORE EVIL RECURSIVE BUSTUP. Problem was due to calling pthreadgetspecific in callinto_lisp without first saving some registers it wanted to trash. Juho helpfully pointed out another crappy-editing-induced potential bug, too. Obviously it's bedtime.

I don't think I've mentioned skating yet all year#

Tue, 08 Feb 2005 00:58:28 +0000

I don't think I've mentioned skating yet all year. Well, I've been skating. Lots. Um. I joined the Londonskaters Speed Team, so some of that skating could even be dignified with the name "training".

Here, in case you cared, are two graphs derived (by gpsman: I haven't resuscitated gpskate yet as I want to get a working threaded sbcl on my dekstop for it first) from my gps data on evenings last week:

This is a so-called "Long Slow Skate" from last Wednesday: ten laps of a loop concentrating on different aspects of technique on each lap. You only see 9 and a half here as the gps is slow to get a fix while moving, and it was too cold to stop.

This is the log from marshalling the Friday Night Skate two days later.

You will observe

I've just registered for the European Common Lisp Meeting in April: flights, hotel,#

Mon, 14 Feb 2005 22:57:16 +0000

I've just registered for the European Common Lisp Meeting in April: flights, hotel, conference, the works. I'll be arriving on Friday so I can do the Amsterdam Friday Night Skate first...

In other news#

Tue, 15 Feb 2005 00:24:56 +0000

In other news...

I feel compelled to share this, just because it took so long#

Sat, 19 Feb 2005 02:06:24 +0000

I feel compelled to share this, just because it took so long. It may yet prove to be utterly useless.

I remarked in my previous entry that I was playing with database APIs in an attempt to avoid Perl: this is related. If you look at the Perl Cookbook, or even read a lot of Perl code written by people who have, you find that over half the recipes basically read incoming data (from a database query or a file or something), whack it into a hash or hash of hashes, then when they've collected everything they iterate over or otherwise traverse the hash contents to get the data out in a more useful format. The classic example is finding the n most common words in a file: for each word we read we look it up in the hash and either add it with value 1 if not found, or increment the value if it was. At the end of the file we have a hash of word frequencies we can easily iterate over, sort or whatever.

You could do that in CL with hash tables but, well, try it and you'll see it ends up being a lot more verbose - especially if you want to have "multidimensional" tables - hashes inside hashes.

(gethash "quux" (gethash "bar" (gethash "foo" *table*)))
and that's without checking that the intermediate values exist. And hashtables don't print in readable format either. And there's no relationship between the order you put elements in and the order thay come out in - not even a dependable happens-to-work-this-way-but-the-same-way-everywhere relationship as Perl gives you.

Plists are nice, though. They're readably printable. I happen to like that they have fewer parens than alists. They don't randomly shuffle themselves around when you're not looking. You can use destructuring-bind to pick them apart conveniently, too (perhaps this is a more compelling advantage than some of the previous). So, I wanted nestable plists. And as it's now 2:33AM I can't be bothered to relate the whole epic voyage of define-setf-expander discovery (some other time, perhaps) so I skip straight to the answers. First, an example

DBS> (let ((l (list :foo 1 :bar 2)))
  (setf (ref l :foo :ban :barry) 17)
  (setf (ref l :boz) 14)
  (format t "-= ~A ~%" (ref l :foo :ban))

-= (BARRY 17) (:BOZ 14 :FOO (:BAN (:BARRY 17)) :BAR 2)

and here's the code. Some of the hard bits were taken from SBCL's define-setf-expander form for getf.

(defun ref (plist &rest keys)
  (reduce #'getf keys :initial-value plist))

(defun %put-ref (new-value plist key &rest more-keys) ;; not quite Perl-style autovivification, but we do create ;; appropriate list structure for intermediate keys that can't be found (unless (listp plist) (setf plist nil)) (let ((sub (getf plist key)) (val (if more-keys (apply #'%put-ref new-value sub more-keys) new-value))) (if sub (progn (setf (getf plist key) val) plist) (list key val plist))))

(define-setf-expander ref (place &rest props &environment env) ;; %put-ref may cons new structure or mutate its argument. ;; all this magic is just so that we can ;; (let ((l nil)) (setf (ref l :foo :bar) t)) (multiple-value-bind (temps values stores set get) (get-setf-expansion place env) (let ((newval (gensym)) (ptemps (loop for i in props collect (gensym)))) (values `(,temps ,ptemps ) `(,values ,props ) `(,newval) `(let ((,(car stores) (%put-ref ,newval ,get ,ptemps))) ,set ,newval) `(ref ,get ,ptemps)))))

I'd like to add a postscript to the preceding: this is not set in#

Sat, 19 Feb 2005 02:44:32 +0000

I'd like to add a postscript to the preceding: this is not set in stone. (1) I'll probably hack it for some looser equality predicate than EQ. (2) To cope with uses like (incf (ref thing :el)) it would be very nice to pass an optional default. Now is however not the time to decide which arg the default will be, but it's looking kind of non-obvious at present.

Do POSIX subcommittees ever look at each others' work#

Thu, 24 Feb 2005 21:31:53 +0000

Do POSIX subcommittees ever look at each others' work? The implementation of interrupt-thread is made more complicated by it not being possible to sigqueue a thread, and likewise not being possible to pthread_kill and pass any data to the thread being signalled. So, we need something held per-thread to indicate what code to interrupt it with, and then some stupid locking regime so that it can be interrupted from two other threads at once without something weird happening. OK, it's not rocket science, and scalability arguments probably don't matter too much as we don't really expect interrupt-thread to be used in expected-to-be-fast code anyway. It's still annoying, though.

I still haven't bought a new laptop; I'm still trying to figure out whether I actually need one or not: so far, the only requirement I've identified is to be able to IRC in front of the TV from time to time, and that's not pressing really. I did also wonder for a while whether I could use a PDA, but after thinking a while longer, maybe I can get away with a text file instead.