Jim Blandy once made the interesting point to me that the way to specificy a compression program is simply to specify its format -- that is, how to decompress it. The format also a strong, though not definitive, hint toward the compression algorithm. Now, that leads to a really wild thought: what if you had a tight little language, a kind of byte-code, for describing how to decompress a file? That is, a compressed file would be program in this language, only most of the bytes of "program code" would really be data bytes. But every now and then there'd be a byte sequence saying "go back 200 bytes and take the next 30 bytes from there" and stuff like that. All decompression programs would therefore be the same program (!), namely an interpreter for this language. The point is that by thinking of the compressed format as a language, the format could become totally independent of the algorithm used to create the file. Assuming the format were well-enough designed to specify any sequence of expansions, backtracks, whatever, then any program that could produce files in this format would be a compressor. Whether a good compressor or not would be up to the authors, but there's no reason for the format to restrict the compression ratio. You'd have to know a lot about compression algorithms to design a good Universal Decompression Language, that's for sure. If you knew what sorts of instructions come up in current compression formats (they are, after all, already languages, and their decompressors are interpreters), then you could probably do a good job. Anyone feel like having a go at it? Jean-loup?
A Device to Automagically Detect Misplaced Books on Library Shelves. [ by Karl "Get Rich Quick And Then Eat Out Forever" Fogel ] It's a waste of time for humans to have to worry about mis-shelved or lost books in a library. The task of detecting misfiled books can be wholly automated. First, insure that each book has a bar-coded Dewey decimal number label on its spine. All books need to have their labels at approximately the same height from the shelf (from the bottom of the book). Somewhere near the base is probably best. Next, a track (like a monorail train track) running the length of the shelf is installed. It can be partially hidden underneath the shelf if it is deemed unsightly, but it must run the full length of the shelf. To detect if there are any out of order books on the shelf, a barcode-reading device runs along the track, going from one end of the shelf to the other, and it scans at the height of the labels on the book spines. It has some simple computational ability (or perhaps it communicates with a smarter device somewhere), and signals whenever it encounters an out of order book. If it's smart enough, it can probably be programmed to save its state as it is manually transferred to the numerically next shelf (or maybe the tracks can be designed to lead to the next shelf, until an aisle needs to be crossed). If it's a little smarter than that, it can be programmed to stop on certain Dewey numbers and emit a different signal; this way, librarians can be searching for books reported as lost while also insuring that the shelves are in order. While tracks are needed on every shelf for this to work, each library will only need one or two of the actual reading devices, since there's no need to scan all shelves simultaneously. -*- -*- -*- -*- -*- -*- -*- additionally -*- -*- -*- -*- -*- -*- -*- It's probably a good idea to give the reader some smarts (or have it communicate with something smart), because it can be used for all sorts of statistical analyses of the library's collection while it checks the shelves. The reading window should also have adjustable height, in case some shelves simply cannot have the track at the optimum location, or have oversized books (although technically that shouldn't matter), whatever. For places where no track is available at all, it should operate as a handheld device, coping with the uneveness of human movement. This should not be difficult, since the library scanners at the circulation desk already seem to cope with that.
If directories are like folders or rooms, why is it that when you enter them you can't see who else is there? How about an operating system that shows you who (or whose processes) are active in the current directory, perhaps by providing a [WHO] button or cluster in the GUI. Computers are as much communication devices as anything else these days. They shouldn't hide other peoples' presence unless asked to.
I'd like to be able to run a program (a "hook") whenever a file changes, without polling. This way CVS could transmit diffs on commit, because the first time a file in a working copy got modified, CVS would be "hooked" into saving a pristine copy somewhere (under CVS/, probably). Come commit time, it can diff the modified copy with the pristine copy and just send the diff. This does not double storage requirements (like the usual diffcommit scheme), because only modified files need pristine copies saved. The Linux kernel could do this...
ask me about this
Suppose you have ambitions to a political career, but also want to keep a diary. Recent events make it clear that your diary could be subpoenaed at some point by a hostile Senate Judiciary Committee. What to do? Merely encrypting it and keeping the key to yourself won't work, as they can subpoena the key just like they did the diary. Yecch. Do you really like the idea of Alfonse D'Amato having any encryption key of yours? I didn't think so. A solution, of sorts: encrypt each entry and *throw away* the key -- relying on Moore's Law and advances in decryption techniques that hopefully will make it possible for you to decrypt your diary about the time you retire and wish to write your memoirs. This technique is not recommended for control freaks.
To: firstname.lastname@example.org Subject: now, *this* I don't have time for, right? --text follows this line-- I had an idea last night. Remember how you told me that you saw Noam Chomsy speak, and he gave examples of such egregiosity as the NYT wildly mistranslating Arabic signs at a demonstration, right? Well, I was thinking that the Net is a really fine distributed proofreading system, and for each blatantly wrong fact that shows up in the media, there's probably at least one person on the Net who noticed it and is qualified to correct it -- if only there were a centralized collector and distributor of corrections that they knew people could consult. Nobody has to do too much work, just send off some mail when they happen to see an error in their "field of expertise". Important omissions in the news could be reported too, but the line there is fuzzier and it might be good to make a separate section for those. I'd like to start such a service. The World Wide Web would be a good place to put it; you could have hyperlinks associated with each article, showing the submitter(s) of the correction (those who want their names used, at least). It could be available by mailing list as well, in which case the submitters would be listed right with the blurb, or maybe in a separate section at the end if there are too many per blurb. Needless to say, automatic tools would do most of this maintenance... and I'd have to learn about mailing-list software and write the tools, probably, mmmm... Here's a sample first "page" of _The Free Electron_: -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- ** The Free Electron (Daily) ** 1. Arabic Sign Mistranslated (NYT, April 17 199x, page A1, photo at upper right) The placard being held by the demonstrator in the center of the photo says "Freedom for Journalists", not "Long Live Our Ruthless Dictator" (which the NYT claimed in the caption below). <> SUBMITTERS <> 2. China's Foreign Debt Higher Than Claimed (The Economist, May 32, 199x, page 60, right hand side.) China's total foreign debt is actually 100 billion dollars (800 billion yuan), not the 100 million dollar figure offered by The Economist. <> SUBMITTERS <> 3. UN Population Proposal Veto by US Ambassador Not Mentioned Most newspapers and television news stations, in their reporting on the UN convention on population control, failed to report that James Farright (US ambassador to the UN) again vetoed a measure that would have supplied contraceptives to women in developing nations. The contraceptives proposed included the so-called "abortion pill". <> SUBMITTERS <> [etc, etc] Note: Neither the editors, the contributors, nor the distributors of this document make any guarantees regarding the accuracy of any statements contained herein. Readers with questions that are not answered by the summaries are urged to contact the appropriate submitter(s), not the editors. For subscription information, send electronic mail to BLAH, with FOO in the subject header or first line. Issues are also available on the World Wide Web, http://foo.edu/somepath. Anything else we need to say to avoid legal responsibility for the allegations herein, please consider to have been said. -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- I'm more comfortable with numbers 1 and 2... number 3 is pushing it, but on the other hand it is important that certain things get mentioned. Just have to make sure that the service doesn't get a reputation for slanting toward certain kinds of omissions, because in the minds of some we Netters are all left-wing libertarian types who see conspiracies everywhere. I don't mind that reputation except that there is a grain of truth in it, and one would have to be careful not to favor certain flavors of submissions. But I think that can be worked out, and anyway, factual corrections can be put in a different section from the other stuff. What do you think? Karl
Lots of people make predictions -- economists, sociologists, politicians... These predictions are rarely checked for accuracy later. What if we had a server where people could register predictions (made by themselves or other people) along with a date to check back. People can register for auto-notification; on or just before that date, email will be sent to the original poster and all the registrees. The poster can go back and state whether in her opinion the prediction has come true, and other people can leave agreements, disagreements, or general comments about it. Wouldn't it be nice to see, for example, how often the General Accounting Office is right about the costs of some new law? Probably wouldn't hurt to get a statistician to make sure predictors are cut as much slack as they ask for (i.e., margins of error).
From kfogel Mon Apr 18 19:52:30 1994 Status: RO Message-Id: <199404190052.AA00191@phylo.life.uiuc.edu> From: kfogel (Karl Fogel) To: email@example.com Cc: kfogel Subject: dating service Date: Mon, 18 Apr 1994 19:52:28 -0500 It would be interesting to run a trusted dating service, where people mail text and the dater sends it back encrypted according to a combination of the date and some private key known only to the date-stamper. If you mail the date-stamper some of its own output, along with the date it was claimed to have been stamped, it would verify that. Probably the plaintext date would be part of the format of the output; no reason why not, if the cryptographic function is strong. Like a bank's safety deposit box (but cheaper), this would provide an objective verification that someone had a certain piece of information on or before a certain date. This assumes that the dating service is trusted, but people seem to do all right with the anon servers. Boy, I'm just full of ideas lately. Wish I had more time... From: Jim Blandy
To: Karl Fogel Subject: Digital notary Date: Wed, 22 Mar 1995 19:55:44 -0500 Remember your dated idea? Check out: Science News March 4 1995 Vol. 147, No. 9 Page 138 It's done by Stuart Haber and W. Scott Stornetta, both at Bellcore in Morristown, NJ and Surety Technologies in Chatham, NJ. [ See http://www.surety.com/about-surety.shtml for more. -Karl ]
From: Karl Fogel
To: firstname.lastname@example.org Subject: primed Date: Mon, 13 Feb 1995 19:58:34 -0600 No, that's not a verb in the past tense. If there are lots of applications which make use of prime numbers, it's silly to have them all re-computing the same primes over and over. Wouldn't it be nice if everyone could share the primes they'd already found, and annoying duplication of prime-generation code were avoided? /usr/lib/primed would be started up at boot time. It would contain a prebuilt table of the most commonly needed primes (those within the range of unsigned int, probably), and thereafter cache any primes it generates (and of couse it can use them in the generation of new primes). It would be smart about keeping track of whether or not its list of primes has any holes... maybe it could spend its spare time filling the holes and/or leisurely generating new primes. Any program needing a prime would just query primed. We can work out an entire, needlessly overblown protocol for prime requests: give me your highest available prime, all the primes from NUM1 to NUM2 (inclusive/exclusive, in all combinations), tell me if X is prime, feed me your longest contiguous list of primes, just give me everything you've got, give me any random prime... Imagine all the savings we'd get from primed. No more looking through dusty books to see if you can do any better than testing against the first few primes, then taking the square root and dividing by every other integer. No more duplication of the same tired old code among ten different application wanting to resize their hash tables. With primed, you can always be assured that the very latest in prime technology is working for you, that your primes were generated as efficiently as possible... or, at least, as efficiently as the author of primed knows how to generate primes. -Karl, who is not learning how to use the GMP library when he should be working on a gene sequence editor.
hmmm... what happens when you take the same number, N, in several different bases and add its digits? What patterns emerge? Time for some scheme code...
From: Karl Fogel
To: email@example.com Subject: topology of the WWW (this is not humor, just me rambling) Date: Sat, 11 Nov 1995 01:25:21 -0600 It occurs to me that the Web has a certain topology, one that can be described more specifically than just "lots of pages with lots of links to other pages" :-). Topics often seem to "cluster". That is, the pages devoted to a particular topic all have a tangle of links pointing from one to another, producing many cycles. On the other hand, we have "gateways" into these clusters, these being pages which link to a cluster member but are not linked back to by many pages in the cluster (define "many" any way you want, it's all very vague anyway). Since one can probably start from any page on the web and find a cycle back to it eventually, the distinguishing characteristic of the clusters must be the shortness of the cycles in them. It's certainly not necessary that they be direct A <---> B cycles (there's some technical term for this, right?)... in fact, in the particular topic that made me think about this, Chinese language related pages, there are many examples of slightly longer cycles which do confine themselves to the topic (i.e., A --> B --> C --> A, where A, B, and C are all exclusively devoted to Chinese language stuff). A page can be a member of multiple clusters, of course, which makes this all a little hard to visualize in three-space. And I'm not totally convinced yet that the topic-specific cycles are really automatically distinguishable from (i.e., usually shorter than) just-there cycles, because I always have the crutch of being aware of the topic when I notice cycles. Some things to ponder are: 1. Are there any biological structures which have a similar topology? (Brain? Maybe the liver? I don't know enough...). If so, is the topology an important part of that structure's function? 2. Are there other things in nature (non-organic) which are like this? 3. Would it be possible for a web-bot to crawl around gathering statistics about clusters? If so, could the results be realized graphically in a useful way? Could a broad "topic map" of the Web be made? [ Answer to first question is almost certainly "Yes", of course. I don't think it's necessary that the bot know when it's "on a topic"... in fact, it's probably better that it *can't* tell. ]
The Perfect Life Program has not been written yet. Xlife has zippy algorithms, but a less-than-ideal interface. A good life program & interface would have: - clear obj (clears everything touching CELL) - run undo (back-to-last-initial-state) - edit undo (undo recent edits, as in de-"clear obj") - load & save, of course - rotate obj - every five gridlines highlighted (like graph paper) - (optional) when turn on or off a cell, thin line over all other cells in that row, col, & diags, so user can easily sight long distances. - infinite universe, of course - zoom & swivel - oases (cute, but not deep) - gardens of eden (deep, but not cute) - a library of common objs (see ~/etc/life.patterns) - gridlines optionally off (at run-time) - a collision explorer (as Jim described)
I'll have to read most of Schneier before I can do this, but: 1. It encrypts messages according to a key, which must be prearranged with the intended recipient (and hopefully with no one else!). 2. The algorithm uses variable-length keys (the longer the stronger). 3. It calculates the key from a plaintext passphrase. The longer the passphrase, the longer the key, the longer the key, the stronger the encryption. 4. It would be nice if snatches of English text were as likely as random garbage text to generate good keys, but this is not a design requirement. Depending on the algorithm, the question of "good" keys vs. "bad" keys may not be very relevant. To encrypt a message, invoke the program on the message, typing the passphrase when prompted. The program does the rest, calculating the key from the passphrase according to some deterministic algorithm by which the same passphrase always produces the same key. It writes the ciphertext to file or stdout as desired. Neither passphrase nor key ever exists on disk (unless you choose to be that insecure); the cleartext need never exist on disk either if you're really paranoid. All memory is carefully zeroed. I can't do anything about swapping, but you can limit its likelihood by controlling how much real memory you have and how much of it is used by other processes. The program decrypts the same way -- invoke it on the ciphertext, type the passphrase when prompted, and read the plaintext on stdout (or in a file if you explicitly ask). As you can see, there is nothing revolutionary about this. It's good old-fashioned encryption. The reason I want it is that it's USEABLE -- I can send my friends reasonably secure messages without thinking too hard, as long as they know the passphrase too. I don't know of any equally useable program out there. PGP can do conventional encryption, but it's unwieldy (IMHO) and still stores the key on disk (albeit encrypted with its own passphrase). I want this encryption program because I might actually use it. It should be as secure the algorithm and key are -- there is very little to attack in the protocol. You know a passphrase, your friends know it, and therefore you can all send secure messages. That's it. There are no confusing key-management techniques or "trust" networks to maintain. Of course, it can't protect against someone snooping your keystrokes (or network-sniffing, if you're typing across a LAN), but then nothing can protect you against that. It doesn't do digital signatures, or allow you to converse with strangers. This is okay -- sometimes it's less important how many things a product can do than that it do well what things it does do. Like that last sentence, for example.
I hate the lost-in-hyperspace feeling that often comes so quickly when reading a hypertext document or browsing through a hyperlink universe. What I want is an actual *map*, that shows me where I am in relation to everything else. (If everything else is too much, maybe it could just show me where I am in relation to where I've already been.) I want the map to be visible at all times, but not so large that it obscures a lot of my viewing area. One solution is to to have it occupy a little xbiff-sized area off in a corner. The outline of the hyperstructure would be clear from looking at the map, and my current location would be highlighted in red or something, but none of the node names would be legible at that resolution. In order to see the map more clearly, I'd click on it -- the mouse buttons would have somewhat the same effect they do in xdvi, zooming into the map so I could read the node names and follow the connections clearly. However, the behavior would be slightly different. In xdvi, you never affect anything by clicking on the document; you just get different levels of zoom. I want to be able to use the map for travel as well as navigation. So maybe it should behave like this: (Let's assume one mouse button for simplicity's sake). Click on the map and get a larger, zoom-window over that area (if you want to see the area where you currently are, you'll just have to click over it). Once the zoom-window pops up, however, the mouse pointer suddenly takes on a new role. It becomes a crosshair that is capable of jumping you to a new node. Each time it is passed over a node, the node highlights (meaning "release now and this is where you'll be"). So moving the mouse doesn't necessarily move the zoom-window (unlike xdvi). Instead, the zoom-window is dragged around whenever the mouse pointer hits an edge, so you *can* still navigate over the whole map. Perhaps you don't want to change your current position -- you just wanted to browse around the map. Hmm, well, in that case, maybe we should make a simple release not have any effect, but another click while dragging would cause the node-under-pointer to be jumped to. How would that work in a single-button-mouse universe? Have to think about this part of the interface some more, I guess. You could have a special command that meant "make this node be root", to uncrowd your map and get a new viewpoint on things.
Fast Database Indexing: this needs to be fleshed out some more, but... The reason we don't index every column (i.e., invert on every possible key) in a database is that maintaining the indices takes up too much space. The price of speed is space; that's why most systems allow you to choose which attributes to index. If indices could be shared as far as possible, space might be saved. But discovering how the data can be shared usually requires semantic knowledge about the database's contents, which allows a human being to carefully construct the index-builders. What if (like automatically-generated Huffman tables and fractal compression) the process of discovering what can be shared could be automated? Examine Sybase's patent for fast indices...
From: kfogel (Karl Fogel) To: firstname.lastname@example.org Cc: kfogel Subject: thought of the day Date: Mon, 28 Nov 1994 10:52:37 -0600 I am forced to use GNUS again, and am in severe pain every step of the way, of course. I'm unsubscribing from a lot of groups that were born after the last time I read news, and I realized that it would be very nice if GNUS took advantage of the heirarchical nature of newsgroups. For example, this: 24: misc.forsale.computers.mac-specific.cards.video 77: misc.forsale.computers.mac-specific.misc 62: misc.forsale.computers.mac-specific.portables 92: misc.forsale.computers.mac-specific.software 89: misc.forsale.computers.mac-specific.systems 229: misc.forsale.computers.memory 113: misc.forsale.computers.modems 55: misc.forsale.computers.monitors 68: misc.forsale.computers.net-hardware 89: misc.forsale.computers.other.misc 57: misc.forsale.computers.other.software 52: misc.forsale.computers.other.systems 41: misc.forsale.computers.pc-specific.audio 53: misc.forsale.computers.pc-specific.cards.misc 55: misc.forsale.computers.pc-specific.cards.video 93: misc.forsale.computers.pc-specific.misc 109: misc.forsale.computers.pc-specific.motherboards 117: misc.forsale.computers.pc-specific.portables 147: misc.forsale.computers.pc-specific.software 97: misc.forsale.computers.pc-specific.systems could be contracted to this: < misc.forsale.computers.mac-specific ... > 229: misc.forsale.computers.memory 113: misc.forsale.computers.modems 55: misc.forsale.computers.monitors 68: misc.forsale.computers.net-hardware < misc.forsale.computers.other ... > < misc.forsale.computers.pc-specific ... > What does this remind you of? The phylo browser, of course. GNUS should probably even have some outside program that does the hard work of getting newsgroups, sorting, threading, etc (maybe it does now, but if so, it's slow). So, dream project for today is rewriting GNUS along a phylo-browser model. :-) -Karl
From kfogel Mon Jul 1 22:54:21 -0500 1996 From: Karl Fogel <email@example.com> To: firstname.lastname@example.org Reply-to: email@example.com BCC: Jim Blandy <firstname.lastname@example.org> Subject: Possible solution for trademark disputes? Emacs: the road to Hell is paved with extensibility. My apologies for adding to your undoubtedly huge mail pile on this subject, and I hope my comments are worth your time. I read today's New York Times article on the growing number of domain name disputes involving trademarked names, and thought: there might be a solution that makes the whole problem simply go away. 1. Create a new top-level domain (call it "r.") for holders of registered trademarks. The domain request forms for this domain will make it clear that one can ask for domain "foo.r" only if one owns the registered trademark "foo". The fact that the domain request form clearly spells out this condition should speed courtroom resolution of any conflicts that still arise. Internic might charge extra for registering such domains and perform the trademark verification itself, even. 2. Create another new top-level domain (call it "alt.", after Usenet), which is run on absolutely a first-come, first-serve basis, and the domain request form will make this clear, too. It would (presumably, though the courts have final say in this) be okay to register someone else's trademark in this domain, since the FQDN itself would make it clear that the owner of the domain is not necessarily the owner of the trademark. The public would catch on pretty quickly and be able to distinguish identities, which is the main purpose of trademarks anyway. 3. Existing .com domains would not have to change, and I suppose existing legal disputes would have to be settled somehow (hopefully some of the participants would simply agree to use the new domains). Whether .com would continue to accept new domain requests, and if so under what policy, is a question I haven't thought much about... Hopefully, companies won't get some silly idea that having a ".com" domain implies some sort of ground-floor cachet that ".r" or ".alt" wouldn't have. However, I am hopeful that most are more sensible than that, and realize that the important thing is that people know how to find them, a property which this scheme preserves. That's the plan in a nutshell. Details have to be mulled over: for example, I don't even know whether trademarks are an international namespace or mainly a US namespace. But the general idea is that this kind of problem can be solved by creating a few new top-level domains. I hope this suggestion is helpful. Good luck, Karl Fogel <email@example.com>
also, how rm -r in dired? Dang it, it should be a real shell almost...
read Asimov's "The Genetic Code", read Szekely's "From DNA to Protein", read Knuth, excurse in Robert Young's "Excursions in Calculus", learn calculus right. Read some intro to chem books. Sheesh -- take a year off and read everything.
M-x apropos and friends ought to use buffer "*Apropos*", not the *Help* buffer, because one wants to refer to the results of the apropos in getting further help.
In C mode, a "open this include file" command.
dymamic completion in query-replace prompts.
make an xwin buttonbar utility that takes executable names as its commline params, and icons if they exist. Allow a default icon directory to be searched, too. It would be started from .xinitrc or something...
make an XBillboard that can leave a message for other people to see on your screen. Big Window, big font, but constantly changing -- can it disable the screensaver?
now make pushd/popd equivalents for projects: pushd: pops over to another project, pushing it to the front of the list and going to it's default buffer/file popd: should we even have this? it's effect will be to bury the project at the end of the alist. helpers: one that moves PROJ to front of alist, and one for NTH proj one that moves a file (we need a better name) within the proj to the front. No other side effects in these, do everything else afterward. i.e.: make a function that automatically uses the now front proj, etc...
buffer rings!!!!! next-buffer-in-ring moves you to the next one in the list: takes ring as arg: ring is usually a digit or something: like registers: prefix args do the obvious: in Emacs 19, it will use C-c 1, etc... okay -- to implement the assocced buffer rings, just have each buffer know which ones it is associated with. Then successive C-c x's display the ring circularly in the minibuffer. When you reach the one you want, hit RET and switch to buffer is called on it. (see the .mailrc for how to make emacs eval something as it finds a buffer). Yeah!
An X program for rebinding keys & mouse buttons to WM functions, like MSWINDOWS or the Mac do, instead of pharting around with little text files that you need a Ph. D. to modify correctly.
From firstname.lastname@example.org Wed Oct 16 06:46:54 1996 Received: from ynu38.ynu.edu.cn ([22.214.171.124]) by totoro.cyclic.com (8.6.9/8.6.9) with ESMTP id GAA10742 for
; Wed, 16 Oct 1996 06:46:36 -0500 Received: (from kfogel@localhost) by ynu38.ynu.edu.cn (8.6.12/8.6.9) id MAA03771; Tue, 15 Oct 1996 12:23:50 +0800 Date: Tue, 15 Oct 1996 12:23:50 +0800 From: Karl Fogel Message-Id: <199610150423.MAA03771@ynu38.ynu.edu.cn> To: email@example.com Subject: Karl: remember the PCP-based encryption scheme... X-Windows: garbage at your fingertips. put this in your ideas file when you get back (why, that's almost as good as actually implementing it!) Ever yours, Wilkins Micawber, Esq.
`push' records buffer, file, and point so you can go off and fix the bug in your debugger that you discovered while debugging another program, and then fix the bug in your editor that you discovered while debugging the debugger, and so on... and return from it all gracefully without forgetting what you were trying to do in the first place. maybe use `recursive-edit'? Of course, one could just set a bookmark at a place and remember what one was doing there. Think about this.
(Back to Karl Fogel's home page.)