Announcing darcs-monitor 0.3.1

Darcs-monitor will send email to a specified recipient about new changes added to a specific darcs repository. It can be run as an apply posthook (resulting in near-instantaneous “push” emails), or periodically from Cron, or occasionally by hand, whatever seems most convenient.

This new release (0.3) contains the following changes:

  • there is now support for the %CHANGES% and %SHORTREPO% substitutions in the template
  • a default template is now provided
  • ' and " entity references in darcs changes –xml is now supported
  • patches with just the author email address (no real name) are now handled correctly
  • when multiple emails are sent, they are now sent in chronological order
  • emails are announced to the user

The minor update 0.3.1 brings the documentation up to date.

Benja Fallenstein and Benjamin Franksen provided some of the features and bug fixes in this release. My thanks to them 🙂

You can get it by darcs at http://antti-juhani.kaijanaho.fi/darcs/darcs-monitor/ (darcsweb
available
), or as a tarball at http://antti-juhani.kaijanaho.fi/software/dist/. It depends on mtl and
HaXml and is written in Haskell, naturally. It has been tested only with GHC 6.6 so far. For installation and usage instructions, refer to the README at any of the locations above.

Please note that this software is very new and thus can be buggy. As with any email-sending software, bugs can result in major annoyance; user caution is warranted.

Debian, eräs Linux-versio eli miksi Debian on cool

(Tämä on aiemmin tänään pitämäni luennon käsikirjoitus. Itse luennossa käytin käsikirjoitusta vain tukena, en lukenut sitä ääneen.)

Minä olen Antti-Juhani Kaijanaho ja olen Debian-kehittäjä. (Hei, Antti-Juhani!) Tarkoituksenani on kertoa teille hieman Debianista. En aio näyttää teille, kuinka sitä käytetään tai kuinka se asennetaan, sillä Linux kuin Linux ei juuri toisesta eroa käyttäjän näkökulmasta. Sen sijaan aion tuoda esille, mikä tekee Debianista poikkeuksellisen. Väitän, että Debian on cool, käyttää sitä eli ei.

* * *

Tarina alkaa yli kaksikymmentä vuotta sitten Amerikan Yhdysvalloissa, Massachusettsin teknillisen korkeakoulun eli MIT:n tekoälylaboratoriossa. Eräänä päivänä heiltä hajosi laboratorion tulostimen ohjausohjelma. Tekoälylaboratorion työntekijät olivat kokeneita ohjelmoijia. Taitoa siis kyllä olisi löytynyt vian korjaamiseen, mutta ohjelman valmistaja kielsi. Tiedättehän, ohjelmaan sai laillisesti koskea vain sen valmistaja. Tietääkseni valmistaja ei pyynnöistä huolimatta koskaan korjannut vikaa. Tekoälylaboratoriossa jouduttiin tyytymään rampaan tulostusjärjestelmään.

Stallman aloitti 1980-luvun puolivälissä projektin, jonka tarkoituksena oli luoda ohjelmia, joita nämä ongelmat eivät koske. Hänen tarkoituksenaan oli luoda kokonainen käyttöjärjestelmä ja siinä toimivat hyötyohjelmat, jotka olisivat vapaasti käytettävissä ja muokattavissa. Hän antoi järjestelmälleen nimeksi GNU.

Vuonna 1991 GNU oli lähes valmis. Puuttui vain käyttöjärjestelmän ydin, se osa, jota pidettiin kaikkein haasteellisimpana. Samaan aikaan Helsingin yliopistossa alkoi leikkiä uudella PC:llään opiskelija nimeltään Linus Torvalds. Hän ei kuulunut GNU-projektiin, vaan hän alkoi rakentaa omaa käyttöjärjestelmän ydintään lähinnä kaiketi opiskelutarkoituksessa — niin, ja hauskanpitotarkoituksessa. Meillä nörteillä on omalaatuinen käsitys siitä, mikä on hauskaa.

Vallankumouksellista Linusin ytimessä, jota alettiin pian kutsua Linuxiksi, ei ole sen teknisiset ominaisuudet. Tuohon aikaan uskottiin, että laajat ja monimutkaiset tietokoneohjelmat on laadittava pienen porukan voimin; ajateltiin, että ohjelmistojen tekemisessä pätee vanha sananlasku kokkien määrästä ja keiton laadusta. Alan piireissä tätä sanotaan Brooksin laiksi[1]: “tekijöiden lisääminen myöhässä olevaan ohjelmistoprojektiin myöhästyttää sitä entisestään”, toisin sanoen ihmiset ja aika eivät ole tämän ajattelun mukaan vaihdettavissa toisikseen. Käyttöjärjestelmän ydin on mitä suurimmassa määrin monimutkainen ohjelma.

[1] Ks. Frederick P. Brooks: The Mythical Man-Month: Essays on Software Engineering. Addison-Wesley, 1975. (20th anniversary edition: Addison-Wesley, 1995.)

Linuxissa hämmästyttävää on ollut se, että sen laatu ja kehityksen nopeus on parantunut sitä mukaa kun sitä kehittämään on tullut lisää ihmisiä. Kun Linus antoi sen ensimmäistä kertaa julkiseen jakeluun vuonna 1991, ei sillä tehnyt juuri mitään. Kolme vuotta myöhemmin se oli saavuttanut 1.0-version, joka oli jo aika käyttökelpoinen. Tässä vaiheessa Linuxia oli ollut kehittämässä 80 ihmistä. Tällä hetkellä uusin versio on 2.6.21, johon mennessä kehittäjiä on ollut yhteensä 482. Silti sen laatu on parantunut eikä sen kehitys ole lamaantunut!

Selitys tälle ihmeelle löytyy siitä, että Linuxissa on paljon erilaisia osa-alueita, joita voidaan kehittää toisistaan erillään ilman, että ne kovin pahasti haittaavat toisiaan, kun järjestelmällä on arkkitehtuuri, joka määrittelee näiden osa-alueiden väliset rajat selkeästi. Linuxin arkkitehti on Linus Torvalds, joka määrää, missä on kaapin paikka.

Internetillä oli myös asiassa merkittävä rooli, sillä sen ansiosta ensimmäistä kertaa ihmiskunnan historiassa oli mahdollista siirtää dataa suhteellisen halvalla maailman toiselle puolelle ja käydä keskusteluja ympäri maailmaa asuvien ihmisten kesken. Linuxa ei olisi voinut olla ilman Internetiä.

Linuxin ympärille oli suhteellisen helppo koota muilta osin täysin valmis GNU. Tämä helppous on toki aika suhteellista, sillä erillisistä paloista piti kaikesta huolimatta koota kokonaisuus, mikä ei ole aivan helppoa, kun otetaan huomioon, että palat on laadittu toisistaan melko riippumatta ja ilman keskitettyä koordinaatiota.

Linuxin ja GNU:n yhdistäminen toimivaksi järjestelmäksi oli itse asiassa aika vaivalloista, ja vain omistautuneimmat harrastajat sen jaksoivat tehdä. Se piti vieläpä tehdä joka koneella erikseen. Aika pian ymmärrettiin, että järjestelmän kokoaminen tapahtuu oikeastaan aika lailla samalla tavalla eri koneilla. Luonnollinen seuraus tästä ajatuksesta on, että jotkut ihmiset alkoivat laatia asennuspaketteja eli jakeluita, joissa tuo järjestelmän kokoaminen on tehty valmiiksi.

Varhaisissa asennuspaketeissa osat oli ikään kuin sulautettu yhteen niin, että niitä ei ollut enää kovin helppo erottaa toisistaan tai huoltaa erikseen. Lisäksi ne olivat usein yhden ihmisen showeja ja yleensä kaupallisia yrityksiä.

Ian Murdock perusti vuonna 1993 uuden asennuspakettiprojektin, joka oli kahdella tavalla vallankumouksellinen[2]:

[2] Ian Murdock: The Debian Manifesto, päivitetty 6. tammikuuta 1994.

Sen kehitystyö olisi avointa ja yhteisöllistä, kuten Linuxin ja GNU:n. Debianilla tulisi olemaan runsaasti yhteistyössä toimivia kehittäjiä.

Sen kehitystyö tapahtuisi voittoa tavoittelemattomana vapaaehtoistyönä kuten Linuxin ja GNU:n, mutta se silti olisi tarpeeksi laadukas kilpaillakseen kaupallisten yritysten kanssa.

Molemmat tavoitteet toteutuivat.

Murdock nimesi projektin yhdistämällä oman etunimensä tyttöystävänsä (nykyisen vaimonsa) etunimen kanssa: Deb ja Ian — Debian. Virallisesti projektin tuote on alkuajoista asti tunnettu nimellä Debian GNU/Linux, minkä tarkoituksena on korostaa sitä, että kyseessä on GNU:n ja Linuxin yhteenliitos.

Debianin ensimmäinen virallinen julkaisu oli versio 1.1, koodinimeltään Buzz, joka julkaistiin kesäkuussa 1995. Versiota 1.0 ei koskaan julkaistu harmillisen sekaannuksen johdosta: eräs CD-ROM-myyjä valmisti ja myi erehdyksessä keskeneräistä versiota väittäen sitä 1.0:ksi. Tämän sattumuksen takia jokainen Debianin versio tunnetaan ensisijaisesti Toy Story -elokuvasta otetuilla koodinimillä, ja versionumero julkaisulle annetaan vasta viime hetkillä.

Tällä hetkellä Debianiin kuuluu toista tuhatta äänivaltaista kehittäjää sekä runsaslukuinen joukko äänivallattomia kehittäjiä. Viimeisin virallinen julkaisu on versio 4.0 koodinimeltään Etch, julkaistu huhtikuussa 2007.


[Debianin julkaisujen ajankohdat kuvana]

Alkuperäinen kuva: Martin F. Krafft; muokatun kuvan lähdetiedosto timeline.fig.

* * *

Debian kutsuu itseään “universaaliksi käyttöjärjestelmäksi”. Tälle nimelle on kolme keskeistä perustetta:

Debian toimii hyvin monessa erilaisessa tietokoneessa PC:istä eräisiin kämmentietokoneisiin sekä eräisiin supertietokoneisiin. Se lienee Linux-jakeluista laaja-alaisin tällä kriteerillä arvioituna.

Debianissa on (lähes) kaikki vapaat ohjelmistot: useimmilla käyttäjillä ei ole mitään tarvetta hakea ohjelmia muualta, sillä kaikki tarvittava tulee Debianin mukana.

Debian toimii myös varsin monen muun Linux-jakelun “emona”: nämä muut jakelut ottavat Debianin pohjakseen ja muokkaavat sitä eri tavoin omien tavoitteittensa mukaiseksi. Tunnetuin Debianin lapsijakelu on Ubuntu.

Debianin kehitystyö keskitttyy niin sanottujen pakettien ympärille. Paketti on Debianin kehitystyön yksikkö, yksi paketti sisältää tyypillisesti yhden sovellusohjelman tai yhden ohjelmakirjaston, ja jokaisella paketilla on yksi tai useampi vastuuhenkilö, jotka yhdessä päättävät, mitä paketille tapahtuu. Monet paketit ovat täysin riippumattomia toisistaan, joten niitä voidaan kehittää täysin toisistaan erillään. Tämän takia Debian on onnistuneesti kasvanut varsin suureksi.

On hyvin tyypillistä, että Debian ei ota jotain uutta toimintoa käyttöön, ennen kuin sille on löytynyt laadukas toteutustapa. Tämän ansiosta Debianilla on maine erittäin luotettavana käyttöjärjestelmän koostajana:

Look, this is Debian. They don’t release things until you have to fire rockets at the thing to stop it working 😉
nimimerkki MrNemesis 14.7.2004

Mainio esimerkki tästä on Debianin pakettienhallintajärjestelmä. Debian oli mahdollisesti ensimmäinen Linux-jakelu, jossa oli ohjelmistotuki pakettien asentamiselle, päivittämiselle ja poistamiselle toisistaan riippumatta. Debian oli kiistatta ensimmäinen Linux-jakelu, jolla oli puoliautomaattinen, älykäs pakettienhallinta (“apt”), joka osaa hakea asennuksen ja päivityksen aikana tarvittavat apupaketit käyttäjän puolesta ja joka osaa päivittää järjestelmän uuteen versioon lennossa, usein jopa ilman tarvetta käynnistää järjestelmä uudelleen. Sittemmin Debianin kehittämä Apt-järjestelmä on otettu käyttöön joko sellaisenaan, pienin muutoksin tai kloonattuna lähes kaikissa muissakin Linux-jakeluissa.

Debianin laatu perustuu myös paljolti siihen, että käytännössä kaikki Debianiin asennettavissa olevat ohjelmat löytyvät Debianista itsestään. Tällöin nimittäin ne kaikki noudattavat yhteistä linjaa (“Debian Policy”), joka Debianin tapauksessa on erikseen dokumentoitu (ja josta joskus käydään varsin kiivaitakin keskusteluja).

Debian oli ensimmäinen Linux-jakelua laativa organisaatio, joka antoi yksipuolisen lupauksen vapaan ohjelmiston ideologian kunnioittamisesta. Tämä Debianin yhteiskuntasopimuksena (“Social Contract”) tunnettu lupaus sisältää muiden muassa lupauksen sisällyttää jakeluun pelkästään vapaita ohjelmistoja sekä lupauksen pitää kaikki ongelmat julkisina. Harva Linux-jakelu on tässä seurannut Debianin jalanjälkiä.

Debianin yhteiskuntasopimus sisältää liitteen nimeltä “Debianin vapaiden ohjelmistojen ohjeisto” (“Debian Free Software Guidelines”), joka esittelee erään määritelmän sille, mitä vapaalta ohjelmistolta vaaditaan. Tästä dokumentista on pienellä muokkauksella synnytetty avoimen lähdekoodin määritelmä (“Open Source Definition”), ja se on edelleen yksi merkittävimmistä vapaiden ohjelmistojen määritelmistä.

Debianin kehitystyö on puhdasta kolmannen sektorin toimintaa. Debian itse ei maksa palkkaa kenellekään, ja valtaosa Debianin kehittäjistä tekevät sitä harrastuksenaan. Osa kehittäjistä toimii Debianissa ulkopuolisten tahojen palkkaamana.

* * *

Debianilla on maine hitaasta toiminnasta. Maine on pitkälti ansaittu: koska asioita ei yleensä tehdä hutiloiden, voi niiden aikaansaamisessa kestää vuosia. Viimeistä edellinen virallinen julkaisu, esimerkiksi, oli työn alla kolmisen vuotta, kun tavoite on tämän puolikas.

Pitkälti edelliseen liittyen Debianilla on myös maine vanhentuneiden ohjelmistojen julkaisemisesta. On totta, että usein Debianin julkaisuhetkellä ohjelmista on jo tehty uudempia versioita, mutta toisaalta näiden uusien versioiden toimivuus ei ole lainkaan taattua. Sen sijaan Debianin virallinen julkaisu yleensä toimii mainiosti, ja tämä saadaan aikaiseksi testaamalla julkaistavaa versiota kuukausikaupalla.

Debiania on myös haukuttu hankalasti asennettavaksi. Tämä piti paikkaansa vielä puolisen vuosikymmentä sitten, mutta Debianin nykyinen virallinen julkaisu on varsin helppo asentaa.

* * *

En väitä, että Debian olisi aina se ainoa oikea valinta. Useimpien käyttäjien näkökulmasta Linux-jakelut eivät juuri eroa toisistaan, ja valitsee sitten Debianin tai jonkin muun valtavirtajakelun, ei tällä ole suurta merkitystä. Sen sijaan ohjelmistokehittäjien ja asianharrastajien kannalta Debianilla on runsaasti etuja, joita olen edellä pyrkinyt käsittelemään.

Väitän kuitenkin, että Debian on cool.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Share Alike 1.0 Finland License.

Serendipity breaks an important Internet standard – and is proud of it

Originally posted on 2006-04-16.

Clarification 2006-04-19: The misfeature discussed below applies to feeds only, as far as I know, not to regular HTML serving.

Update 2007-05-06: I have just learned that the option in question is Activate strict RFC2616 RSS-Feed compliance. I have no idea when it was added.

While investigating (wearing my hat as the Planet Haskell editor/technician) John Goerzen‘s Planet floods, I stumbled on a very strange misfeature in Serendipity. A HTTP/1.1 client can ask a server to send a file over only if the file has been modified since some date. What Serendipity does is send only those entries dated after the provided timestamp. Now, this might seem like a triviality, but it isn’t. The HTTP/1.1 feature is there to make proxy caching work. It is very important for caching that the file sent is the same, regardless whether the request is “since this timestamp”, or a regular request. Serendipity’s behaviour breaks this very important caching invariant!

What’s more is that Serendipity’s developers seem rather proud of this misfeature. While the feature this misuse of HTTP/1.1 is intended to create is certainly useful, it should be implemented as a separate mechanism, and not by misusing HTTP/1.1 caching! (A separate protocol is probably necessary, perhaps specifying a URI query syntax for this is enough; obviously, one needs to get the aggregators to support this.)

Serendipity will apparently have a configuration option to fix this, but it will be off by default. Serendipity users, upgrade (as soon as it is possible) and mark that option On, to remain compatible with the rest of the Internet.

Looking for dctrl-tools testcases

If you use grep-dctrl, sort-dctrl or tbl-dctrl, I’d like to see your use cases! I’m building a system test automaton for dctrl-tools, and I’d like to include as much real-world examples as possible so that any regressions get found before uploading.

You can send example command lines (and preferably also a test file, unless it’s one of the standard Debian files like Packages) to me by email at <ajk@debian.org>, as a wishlist bug report against dctrl-tools or by a Darcs patch against the experimental repository (see instructions).

Announcing darcs-monitor

There aren’t many features I grew fond of with CVS that I haven’t yet found a satisfactory solution for in Darcs. One of them was, until today, sending commit mails to mailing lists. There are a number of more or less ugly hacks floating around the net, but I never found them very satisfactory, so I wrote my own.

Darcs-monitor will send email to a specified recipient about new changes added to a specific darcs repository. It can be run as an apply posthook (resulting in near-instantaneous “push” emails), or periodically from Cron, or occasionally by hand, whatever seems most convenient.

You can get it by darcs at http://antti-juhani.kaijanaho.fi/darcs/darcs-monitor/ (darcsweb available), or as a tarball at http://antti-juhani.kaijanaho.fi/software/dist/. It depends on mtl and HaXml and is written in Haskell, naturally. It has been tested only with GHC 6.6 so far. For installation and usage instructions, refer to the README.

Please note that this software is very new and thus can be buggy. As with any email-sending software, bugs can result in major annoyance; user caution is warranted.

Introducing Quadmachine II

Quadmachine is a virtual instruction set architecture, designed mainly as a target for simple educational compilers. It has the following noteworthy features:

  • RISC design
  • word size 64 bits
  • address size 64 bits (theoretical maximum memory size 16 exabytes)
  • all memory access is in word units
  • 65534 general-purpose 64-bit registers
  • 2 additional special-purpose 64-bit registers
  • a variant of the “register windows” technique with automatic spilling

All of these, except for the preposterously large register file, are more or less realistic for a 64-bit RISC design. The size of the register file is intended to trivialize register allocation in compilers.

This is the second Quadmachine design. Main differences from the previous design are a move to a load-store RISC architecture and the upgrade of the word size to 64 bits.

There is a software realization of the Quadmachine architecture, with a graphical debug console. It is written in Java for portability; speed was not an implementation concern.

Read more

Dealing with multiple parallel sources of translations

I get translations for dctrl-tools from multiple sources: one translator has direct commit rights to my darcs repository, others bug me; still others use Rosetta (dctrl-tools upstream). On top of this, I just found out that there are active translators working on the Ubuntu branch of dctrl-tools in Rosetta. There have been several cases of different sources of translations having different parts of the programs translated, so it would make sense to combine them somehow.

Dear LazyWeb, how do I combine translations from all these sources?

Graph reduction

Graph reduction is the basic operational model of lazy functional programming. The idea is that the program is represented as a huge λ-term abstract syntax tree, and the program is executed by performing outermost-leftmost β-reductions to this tree, and whenever a subtree must be replaced by another tree (such as, when performing the substitution operation), the root node of the replacee is overwritten by the root node of the replacement (or a redirection node pointing to the replacement) instead of making copies (the body of an abstraction still needs to be copied, of course). The effect is the familiar laziness: when a function refers to its parameter more than once, the argument term is shared between the parameter references instead of making copies, and so any reduction in any one of them is shared by all of them.

For some strange reason, I decided I must write a set of C functions that demonstrate graph reduction. I wrote them, and then in order to test them I expanded them to become a complete implementation of λ-calculus (extended with integers) graph reduction. The program can be found here; it is written in portable ANSI–C. It is able to show the complete trace of reductions. It is intended for demonstrating the technique, and therefore is effectively a stupid interpreter and does not implement any of the sophisticated optimization techniques that industrial-strength functional language implementations routinely use.

Example usage:

$ cat examples/fib
TRUE = \t.\f.t
FALSE = \t.\f.f
IF = \x.x
NIL = \x. IF x TRUE NIL
ISNIL = \x. x TRUE
CONS = \car. \cdr. \x. IF x FALSE (\y. IF y car cdr)
CAR = \cell. cell FALSE TRUE
CDR = \cell. cell FALSE FALSE
MAP = \f. \xs. IF (ISNIL xs) NIL (CONS (f (CAR xs)) (MAP f (CDR xs)))
AT = \n. \xs. CAR (DROP n xs)
DROP = \n. \xs. IF (n = 0) xs (DROP (n - 1) (CDR xs))
TAKE = \n. \xs. IF (n = 0) NIL (CAR xs (TAKE (n - 1) (CDR xs)))
FIBS = CONS (CONS 0 1) (MAP GENFIB FIBS)
GENFIB = \pair. CONS (CDR pair) ((CAR pair) + (CDR pair))
FIB = \n. (CDR (AT n FIBS))
$ ./graph-reduction -t -S10K -H1M examples/fib
graph-reduction 1.0 by Antti-Juhani Kaijanaho, report bugs to antkaij@mit.jyu.fi
[heap_size=1048560,stack_size=2621440]
examples/fib> FIB 3
[...]
1 + (1 + (0 + (\f[4].f[4]) (\y[11].(\x[5].x[5]) y[11] 0 1) (\t[3].\f[4].f[4])))
1 + (1 + (0 + (\y[11].(\x[5].x[5]) y[11] 0 1) (\t[3].\f[4].f[4])))
1 + (1 + (0 + (\x[5].x[5]) (\t[3].\f[4].f[4]) 0 1))
1 + (1 + (0 + (\t[3].\f[4].f[4]) 0 1))
1 + (1 + (0 + (\f[4].f[4]) 1))
1 + (1 + (0 + 1))
1 + (1 + 1)
1 + 2
3
examples/fib>

(In the trace output, each bound variable is annotated by a scope identifier that effectively allows me to ignore variable caputure problems.)

I plant to further extend the language to handle algebraic data types and simple pattern matching, to get rid of the noise of simulating these concepts in the traces.

Technically, perhaps the most interesting part of the program is that it contains a fully portable copying garbage collector.

Haskell responses for Eric Warmenhoven

Eric Warmenhoven asked a couple of Haskell questions. Here are my answers.

BTW, do you want to be added to Planet Haskell? If so, drop me an email.

Also, be sure to subscribe to the Haskell mailing lists.

Where did all the shared libraries go? Turning a Haskell module into a static library looks like it’s fairly straightforward, but it looks like it’s impossible to create a shared library that’s usable by other Haskell programs.

See the GHC FAQ.

Why do header files have a bizzare suffix? If module A uses something from module B and module B uses something from module A, there’s a circular dependency that GHC can’t resolve on its own. The solution to this is to create a “boot” copy of module A that defines the things that B depends on without depending on B. In C this is called a header file. In GHC this is called a boot file and is given the extension “.hs-boot”.

There are no header files with Haskell. Or rather, there are (the .hi files), but they are generated by the compiler when compiling the module. The .hs-boot files are not header files but a workaround for GHC’s inability to compile circularly dependent modules (which the language spec requires).

Why does everyone ignore all the practical stuff? I read through five tutorials before I finally found one (on Monads, of all things) that actually had a usable getArgs example.

Perhaps many people consider the practicals easy and want to discuss the hard things instead.

Where’s the Debian-specific documentation? For example, there’s a GTK module. Where is that? How do I get it? Is there a package for it? If not, how do I make one? (I saw the debian haskell mailing list but didn’t feel like wading through the archives hoping that one of my questions might be answered.)

There is no Debian-specific documentation apart from a draft “policy”.

Googling, I found this repository that contains Gtk2HS debs. Haven’t tried them, though.