Thu, 31 May 2007

Hi Kragen,

* Kragen Sitaker <kragen at pobox.com> [1999-01-20 19:51]:
> The cypherpunks are the only people I remember hearing this
> concept from in the past [that our lives are shaped, regulated,
> by code, so we should manipulate code in order to manipulate
> the shape of society] -- although it is clearly true. The
> technical choices behind the Web, for example, clearly make it
> impossible for noncommercial speech to be widely heard,

which are these choices and which of their specific effects that
make it so? Can you expand on this with a few short notes?

Regards,
-- 
Aristotle Pagaltzis // <http://plasmasturm.org/>

Fri, 18 May 2007

Kragen Javier Sitaker writes:
>                                                  complexity has
>hidden costs --- complex things are less reliable, fail in more
>unpredictable ways, are harder to diagnose problems in, are often
>harder to fix, are usually more trouble to keep running, are harder to
>change (especially to change without breaking), and are harder to get
>to work with other things.

I do not understand why more designers and users of software do
not realize that.

As early as the late 1970s, Dijkstra complained often and
bitterly about gratuitous complexity.

For a while I considered switching from Linux to Plan 9 because 
Plan 9's designers avoided gratuitous complexity.

I did not because it turns out that an even more important factor
is that the designers of my software must have empathy for the
user, and Plan 9's designers have less empathy for the user than
the designers of the Linux software I use (Emacs, Gnome), with
the result that Plan 9 is great for programmers implementing
software similar to Plan 9 (i.e., software that does not have
strong interoperability requirements) but not so great for
general work.

(Plan 9 also does not have a web browser that can handle most 
web pages to be found in the wild.)

Thu, 17 May 2007

A somewhat gullible friend was telling me about this antibiotic she
takes called "propolis", made by bees, and I went to go do some more
reading on the subject.

So it turns out that propolis is not actually made by bees; it's
gathered by bees from nearby plants, and it looks like there's good
evidence that it works.  But its composition varies a lot, and can even
include artificial caulking chemicals that bees gather from nearby
construction projects.

Also, it contains a very large number of different chemicals.

So it's probably fairly safe to take in small quantities, and there is
good empirical evidence suggesting that it is effective; but it's not
consistent in its composition, and at least sometimes, it contains a
wide variety of toxins.

Unsurprisingly, the best overview I've found online is in Wikipedia:
> http://en.wikipedia.org/wiki/Propolis

A 1998 toxicology review:
> http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=9651052&dopt=Abstract

	Propolis is a multifunctional material used by bees in the
	construction and maintenance of their hives. Use of propolis by
	humans has a long history, predated only by the discovery of
	honey. Use of products containing propolis have resulted in
	extensive dermal contact and it is now increasingly being used a
	dietary supplement. Unlike many 'natural' remedies, there is a
	substantive database on the biological activity and toxicity of
	propolis indicating it may have many antibiotic, antifungal,
	antiviral and antitumour properties, among other attributes.
	Although reports of allergic reactions are not uncommon,
	propolis is relatively non-toxic, with a no-effect level (NOEL)
	in a 90-mouse study of 1400 mg/kg body weight/day.

This pharmacopeia site sort of endorses it:
> http://www.pdrhealth.com/drug_info/nmdrugprofiles/nutsupdrugs/pro_0294.shtml
But the best part is the list of references:

	Burdock GA. Review of the biological properties and toxicity of
	bee propolis (propolis). Food Chem Toxicol. 1998; 36:347-363.

	Chopra S, Pillai KK, Husain SZ, Giri DK. Propolis protects
	against doxorubicin-induced myocardiopathy in rats. Exp Mol
	Pathol. 1995; 62:190-198.

	El-Ghazaly MA, Khayyal MT. The use of aqueous propolis extract
	against radiation-induced damage. Drugs Exp Clin Res. 1995;
	21:229-236.

	Grange JM, Davey RW. Antibacterial properties of propolis (bee
	glue).  J.R Soc Med. 1990; 83:159-160.

	Harish Z, Rubinstein A, Golodner M, et al. Suppression of HIV-1
	replication by propolis and its immunoregulatory effect. Drugs
	Exp Clin Res. 1997; 23:89-96.

	Khayyal MT, el-Ghazaly MA, el-Khatib AS. Mechanism involved in
	the anti-inflammatory effect of propolis extract. Drugs Exp Clin
	Res. 1993; 19:197-203.

	Kujumgiev A, Tsverkova I, Serkedjieva Y, et al. Antibacterial,
	antifungal and antiviral activity of propolis of different
	geographic origins. J Ethnopharmacol. 1999; 64:235-240.

	Ledon N, Casaco A, Gonzales R, et al. Antipsoriatic,
	anti-inflammatory and analgesic effects of an extract of red
	propolis. Chung Kuo Yao Li Hsueh Pao. 1997; 18:274-276.

	Lin SC, Lin YH, Chen CF, et al. The hepatoprotective and
	therapeutic effects of propolis ethanol extract on chronic
	alcohol-induced liver injuries. Am J Chin Med 1997; 25:325-332.

	Matsuno T, Jung SK, Matsumoto Y, et al. Preferential
	cytotoxicity to tumor cells of 3, 5-diprenyl-4-hydroxycinnamic
	acid (artipillin C) isolated from propolis. Anticancer Res.
	1997; 17(5A):3565-3568.

	Mirzoeva OK, Calder PC. The effect of propolis and its
	components on eicosanoid production during the inflammatory
	response. Prostaglandins Leukot Essent Fatty Acids. 1996;
	55:441-449.

	Mirzoeva OK, Grishanin RN, Calder PC. Antimicrobial actin of
	propolis and some of its components: the effects on growth,
	membrane potential and motility of bacteria. Microbiol Res.
	1997; 152:239-246.

	Natarajan K, Singh S, Burke TR Jr, et al. Caffeic acid phenethyl
	ester is a potent and specific inhibitor of activation of
	nuclear transcription factor NF-Kappa B. Proc Natl Acad Sci.
	1996; 93:9090-9095.

	Ozturk F, Kurt E, Cerci M, et al. The effect of propolis extract
	in experimental chemical corneal injury. Ophthalmic Res. 2000;
	32:13-18.

	Park EH, Kahng JH. Suppressive effects of propolis in rat
	adjuvant arthritis. Arch Pharm Res. 1999; 22:554-558.

	Rao CV, Desai D, Simi B, et al. Inhibitory effect of caffeic
	acid esters on azoxymethane-induced biochemical change and
	aberrant crypt foci formation in rat colon. Cancer Res. 1993;
	53:4182-4188.

This unethical propolis merchant has a litany of misleading and
contradictory statements on their web page:
> http://www.pureroyaljelly.com/propolis.html
Among other things, they claim that propolis contains 19 known
chemicals, more than 500 known chemicals, that it is a "perfectly
balanced substance", that its composition varies wildly, that it is a
resin, that it is a mixture of resins with other things, and so on.  Oh,
and it implies that penicillin is synthetic.  Not the people I want to
buy my drugs from.

Even this page, which is mostly anti-alternative-medicine, allows that
propolis "has exhibited a variety of interesting antimicrobial and
antitumor properties" in laboratory tests, although it then cites a
20-year-old paper to support its assertion that it "has little practical
use".
> http://www.quackwatch.org/01QuackeryRelatedTopics/DSH/bee.html

This page ("Propolis", by Heather Clay, Printed in Hivelights, Vol 14
#1) discusses how to gather it:
> http://www.honeycouncil.ca/users/folder.asp?FolderID=4667
It warns that the "traditional way" to collect propolis can result in
contamination of the resulting propolis with wood and paint particles,
and recommends regular testing to detect possible lead contamination.

Thu, 10 May 2007

So Mozilla broke on my laptop one day.  I first realized there was a
problem when my friend Kelly tried to use it for Gmail, and clicking
on a certain link reliably crashed the browser.

    (Unfortunately, Kelly didn't realize that when the dialog box
    popped up and said, "Start New Session or Restore Previous
    Session?", the "Start New Session" button should actually have
    been labeled "Discard All of the Web Pages Kragen Previously Had
    Open, Making Him Very Sad".)

There had actually been an incident a few days earlier in which some
unknown page crashed the browser.  After a few "Restore Session"s, the
browser had forgotten most of the pages I had previously had open.
But I figured that this was not likely to re-occur.

But then it did.  After Kelly's problem, there was a page on
www.cnn.com that crashed the browser every time I tried to view it.  I
edited the "sessionstore.js" file (in
.mozilla/firefox/m9e6kquo.default/) to change all the recent URLs to
something that wouldn't work --- mostly by adding "/broken" in the URL
path, e.g. http://www.example.com/foo/bar would become
http://www.example.com/broken/foo/bar.  This let me figure out which
page caused the problem.

At this point, I figured I was running into a browser bug that
probably every Firefox user had in a latent form, maybe one triggered
by my own unusual configuration, and that was only appearing now due
to something having changed on the web.  I asked my friend Meredith
Patterson to look at the page on her Mac OS X browser, but she had no
trouble.

Tracking it down
----------------

I saved the CNN page to my local machine (using Konqueror as a web
browser) and found that it still crashed.  My next priority was to cut
down the crash to a small, reproducible case, so I cut out all the
external links --- inline images, stylesheets, and the like --- by
rewriting "http://" links as "xhttp://" links, which were guaranteed
to not work.

It stopped crashing, so I changed some of the "xhttp://" things back
to "http://" until I found one that made the browser crash again.

I tried running gdb on the Firefox process at this point, but all it
told me was that it crashed while trying to execute a nonsense
address.  No clue about where it jumped to the nonsense address from,
or why, although it did make me feel that the bug was probably fairly
serious and possibly an exploitable security hole.  Eventually,
though, I gave up on the gdb approach.

It turned out that the only external thing needed to reproduce the
crash was a single external JavaScript file, main.js, and the contents
of the page.  (I tried an HTML file with just a <script> tag to run
main.js, but it didn't crash the browser.)  So I saved a local copy of
the file, reproduced the crash with the page using the local copy, and
then added an "x" to the beginning of each function named in the file
so that they wouldn't be called; this rendered the file harmless.
Then, I started removing the "x"es one by one to see where the crash
happened, but I didn't have to go very far --- the first function I
re-enabled, called "cnnHandleCSIs", crashed the browser.

So then I sprinkled "alert" calls through the function to see where it
crashed, and it was on this line here:

    if(document.body && document.body.innerHTML && cnnUseDelayedCSI)

So I evaluated each of the three conditions in Jesse Ruderman's
JavaScript shell, and found that just evaluating
document.body.innerHTML was sufficient to crash the browser.

So I figured something was funky about this particular page that made
it unsafe to evaluate document.body.innerHTML, and so I thought I'd
see whether it was the page in its original form, or something unusual
one of the scripts in the page was doing to it.  I'd already disabled
the links to all the external scripts except main.js, but I removed
all the inline JavaScript as well --- but the page kept crashing the
browser whenever I asked for document.body.innerHTML.

Verifying the package
---------------------

My next thought was to cut the page down bit by bit to figure out
which feature or combination of features was sufficient to cause the
crash.  But at this point I whined about the situation to some of my
friends, and Paul Visscher suggested that maybe my copy of the browser
was corrupted, or something in my profile.  I tried with a fresh
.mozilla directory (mv .mozilla .mozilla-tosave; restart browser;
verify crash; rm -rf the newly created .mozilla; mv .mozilla-tosave
.mozilla)

So I installed the "debsums" package ("sudo apt-get install debsums"),
which verifies files installed from Debian packages to see if they've
been corrupted, and ran "debsums -s firefox":

    kragen at generous:~$ debsums -s firefox
    debsums: checksum mismatch firefox file
        /usr/lib/firefox/components/libgklayout.so

Well, so one of the components of Firefox, a "shared object" or shared
library, had been changed since installation --- fairly unusual!  And
it would make sense that if there were an error in that file, some
normal-ish operations like "document.body.innerHTML" might crash.

So I ran "sudo apt-get install --reinstall firefox", and the problem
went away; the browser no longer crashed on the pages that I'd been
able to reproduce the problem with numerous times before, and debsums
stopped complaining.

The Problem
-----------

I saved a copy of the broken libgklayout.so, and it turned out that it
differed from the correct one only in a single bit.  I opened the two
files with "hexl-find-file" in Emacs and ran "ediff-buffers" to find
the differences between the two, and the differences came down to
this:

Correct:
    002b1250: fea0 000f 8441 0200 0066 83fe 3e76 c166  .....A...f..>v.f
Broken:
    002b1250: fea0 000f 8441 0200 1066 83fe 3e76 c166  .....A...f..>v.f

The broken file had a "10" byte where the correct file had a "00"
byte.  So somewhere along the line, I'd had a single-bit error in a
disk file, one that probably shouldn't be getting modified during the
normal course of operation, and it resulted in all of this
frustration.

The Follow-Up
-------------

Naturally I wanted to see if there were any other packages that had
also been corrupted, so I ran this command:

    debsums -s > all-debsums 2>&1

It found a number of checksums mismatches, like these:

    debsums: checksum mismatch aspell-en file /var/lib/aspell/en-common.rws
    debsums: checksum mismatch aspell-en file /var/lib/aspell/en-variant_0.rws
    debsums: checksum mismatch libpango1.0-common file
        /var/lib/pango/pango.modules
    debsums: checksum mismatch xfonts-scalable file
        /usr/share/fonts/X11/Type1/fonts.dir

There were a lot of packages that didn't have any checksums:

    debsums: no md5sums for binutils

And it had one permission problem:

    debsums: can't open apache2-common file
        /usr/lib/apache2/suexec2 (Permission denied)

I'm not sure why aspell's files are changed; they aren't documented,
as far as I can tell, and they're in binary.  The other
checksum-mismatch files are all "lists of installed stuff", and so
it's OK if they change; they probably should be treated differently by
the packaging system.

Anyway, so I don't know if any of the rest of my disk is corrupted,
but debsums didn't find any problems.

Mon, 07 May 2007

> [text-substitution] turns out to actually be Turing-complete.

http://en.literateprograms.org/Turing_machine_simulator_(Sed)
is a nice demonstration of this property.  He uses sed's branching  
commands, but as we've discussed here before, one can always move the  
control state to the tape.

A lot of computation looks remarkably like text substitution: splice the  
top of a data stack to the top of a return stack, and evaluation turns  
into substitutions at the splice point.  (cf buffer-gap editors)

An interesting exception is the usual sokoban technique, where the entire  
game state lives in the game field and its topology is reflected in how  
the connectivity of the "string" changes depending upon whether one is  
moving horizontally or vertically.

Can REST be seen as another example of letting state live in data?

-Dave

Gaim/Pidgin includes a "Text replacement" plugin, which performs
textual substitutions on your text as you type it --- it looks for
specific strings of text, and if it finds them, it replaces them with
other specific strings of text.

This turns out to actually be Turing-complete.  Here's my .gaim/dict
file, which contains:
1. some shortcuts for Unicode characters; 
2. a simple smart-quotes algorithm (partly due to Aristotle Pagaltzis); 
3. an animation of arrows bouncing back and forth, launched by the
   string @!@;
4. a sort of prototype input method for Runic; if you type
   "$runic$futhark " you will see the runes for "futhark", but I
   haven't implemented most of the runes, nor is it possible to
   backspace easily;
5. and a complete evaluator for Boolean expressions expressed in the
   Laws of Form notation, using (x) to represent a "cross" whose
   content is x.  You launch it by typing ##@ followed by the
   expression expressed as nested parentheses; it transforms your ()'s
   into ⎡⎤'s. You terminate the expression entry by typing a space,
   and as you type further, it will reduce the expression further.

The evaluator is considerably more complex than necessary because I
entered it entirely through Gaim's GUI, which doesn't allow you to add
"ε-productions" --- replacements that delete a string entirely --- so
it represents the deletion of ⎡⎡⎤⎤ with several different contextual
rules, which I think are exhaustive as long as you type a space at the
end of the expression (and could be simplified!).

It would be nicer if you could enter the expressions in the normal
Boolean fashion with and, or, and not operators, and true and false,
rather than Laws Of Form's single N-way NAND.  This is possible to
accomplish, but I'm too sleepy now to figure out how.

I think you can just append this file onto your .gaim/dict and have
it work.  I should probably make a screencast, because this feature
probably won't survive more than a few more versions of Gaim.

COMPLETE 0
CASE 1
BAD |>>>
GOOD ▷

COMPLETE 0
CASE 1
BAD  "
GOOD  “

COMPLETE 0
CASE 1
BAD  ⇇
GOOD ⇇ 

COMPLETE 0
CASE 1
BAD --
GOOD –

COMPLETE 0
CASE 1
BAD !?
GOOD ‽

COMPLETE 0
CASE 1
BAD " 
GOOD ” 

COMPLETE 0
CASE 1
BAD @!@
GOOD ⁅⇉⁆

COMPLETE 0
CASE 1
BAD $*$
GOOD ҉

COMPLETE 0
CASE 1
BAD ##@ 
GOOD .

COMPLETE 0
CASE 1
BAD ##@(
GOOD ⎡##@

COMPLETE 0
CASE 1
BAD ##@)
GOOD ⎤##@

COMPLETE 0
CASE 1
BAD ⇉ 
GOOD  ⇉

COMPLETE 0
CASE 1
BAD –-
GOOD —

COMPLETE 0
CASE 1
BAD ⁅⇇
GOOD ⁅⇉

COMPLETE 0
CASE 1
BAD ⇉⁆
GOOD ⇇ ⁆

COMPLETE 0
CASE 1
BAD ⎡⎤⎡⎤
GOOD ⎡⎤

COMPLETE 0
CASE 1
BAD ⎡⎡⎤⎤.
GOOD .

COMPLETE 0
CASE 1
BAD ⎡⎡⎤⎤⎡
GOOD ⎡

COMPLETE 0
CASE 1
BAD ⎤⎡⎡⎤⎤
GOOD ⎤

COMPLETE 0
CASE 1
BAD ⎡⎡⎡⎤⎤
GOOD ⎡

COMPLETE 0
CASE 1
BAD (1)
GOOD ①

COMPLETE 0
CASE 1
BAD ^2
GOOD ²

COMPLETE 0
CASE 1
BAD _2
GOOD ₂

COMPLETE 0
CASE 1
BAD (2)
GOOD ②

COMPLETE 0
CASE 1
BAD ^3
GOOD ³

COMPLETE 0
CASE 1
BAD _3
GOOD ₃

COMPLETE 0
CASE 1
BAD (3)
GOOD ③

COMPLETE 0
CASE 1
BAD $<3
GOOD ♥

COMPLETE 0
CASE 1
BAD $\<3
GOOD 愛

COMPLETE 0
CASE 1
BAD _4
GOOD ₄

COMPLETE 0
CASE 1
BAD (4)
GOOD ④

COMPLETE 0
CASE 1
BAD (5)
GOOD ⑤

COMPLETE 0
CASE 1
BAD $dragon$
GOOD ⿓

COMPLETE 0
CASE 1
BAD =e=
GOOD €

COMPLETE 0
CASE 1
BAD $runic$ 
GOOD  

COMPLETE 0
CASE 1
BAD $runic$a
GOOD ᚨ$runic$

COMPLETE 0
CASE 1
BAD $runic$f
GOOD ᚠ$runic$

COMPLETE 0
CASE 1
BAD $runic$k
GOOD ᚴ$runic$

COMPLETE 0
CASE 1
BAD $runic$r
GOOD ᚱ$runic$

COMPLETE 0
CASE 1
BAD $runic$th
GOOD ᚦ$runic$

COMPLETE 0
CASE 1
BAD $runic$u
GOOD ᚢ$runic$

Tue, 01 May 2007

Of possible interest is the general linguistic rule that irregular forms  
are like footpaths in a lawn -- they occur in frequently-used areas, but  
disappear with disuse; as a domain becomes obsolete, its vocabulary goes  
regular.  This pattern covers both the pedants (for whom the classical  
form is, like the well-trampled earth of an abandoned path, a sign that a  
word was once frequently wrought, even if the current population never  
uses it) and the hackers (for whom the novel form is, like the fresh cut  
of a new singletrack, a declaration that they frequently work with a word,  
even if the general population never uses it).

-Dave