Older blog entries for cactus (starting at number 148)

Valós halál

Organikus károkozás — ezzé bagatellizálódott a gyilkosság Richard Morgan regényének világában. A könyvben felvázolt jövőben az emberi tudatot ugyanis egy erre alkalmas, tarkóba épített elektronikus berendezés (a tudattok) tárolja, és nem jelent gondot bármikor újraburkolni, átültetni másik—akár szintetikus—testbe. Problémát tehát csak a címadó valós halál, a tudattok megsemmisülése jelent.

Richard Morgan: Valós halál

Morgan sci-fi krimije alaposan körbejárja az alapötlet felvetette kérdéseket. Hogyan viszonyulnak a néhány generáció óta jelen lévő, a tudatot és a testet teljesen elválasztó technikai bravúrhoz az életösztönt milliárd év alatt internalizált emberi lények? Mit jelent a társadalom számára, ha a tehetősebbek megannyi testet és klónt tarthatnak fenn a maguk számára, és az alsóbb osztályok emberöltőinek életét nézhetik végig, gyakorlatilag tetszőleges ideig? Mennyire fontos a testek, és mennyire a személyiségek vonzódása a párkapcsolatokban?

Takeshi Kovácsnak, egy katonai speciális osztag, a Küldöttek veteránjának magánnyomozása jelenti a történetet, amolyan oldschool Philip Marlowe-stílben. Morgan az általa teremtett világról mindig csak apró részleteket mutat, sosem tol az olvasó arcába szájbarágó magyarázatokat arról, ami a XXI. és a XXVI. század között történt. Szerintem ez pozitív.

Ami viszont nem tetszett, illetve inkább csak nem felelt meg a prekoncepciómnak, az az, hogy sokkal modernebb sci-fire számítottam. A magyar kiadás borítója büszkén hirdeti, hogy a regény "Philip K. Dick-díjas", bármit is jelentsen ez, de pont Dick ugyanezt a regényt negyven évvel ezelőtt simán megírhatta volna, mondjuk azzal együtt, hogy az biztos egy kevésbé követhető könyv lenne.

A centrális kérdést jelentő test-tudat dualitást pedig bár körbejárja, de leglényegesebb pontjára mintha félne kitérni. A történetben ugyanis többször szerepel a távtárolás technikája, sőt, a bonyodalmat is ez adja: vagyis hogy egyesek tudatáról időnként biztonsági másolatot készítenek, és szükség esetén, ha a tudattok megsemmisül, innen visszaállítható egy pár órával a halált megelőző állapot. Igen ám, de mennyiben tekinthető ez örök életnek, mennyire jelenti azt a szubjektív én számára, hogy nem kell félnem a (valós) haláltól? Vajon miért érezném súlytalannak a valós öngyilkosságot csak azért, mert halálom után pár órával már újra beburkolnak egy testbe valakit, aki a regénybeli logika szerint én vagyok? Hiszen nyilvánvaló, hogy én én, aki meghúzom a ravaszt, ez a tudat, a maga folytonosságában megszűnik létezni. Akkor hogy is van ez? Az ikertestvérem nem én vagyok...

Syndicated 2007-10-03 18:22:00 from cactus.rulez.org

(cross-posted from here)

Queueing timeouts in JavaScript

I wanted to create a simple animation to illustrate sorting algorithms, using SVG and JavaScript. The basic idea was to present a simple JavaScript API that sorting implementations could use. It turned out I had to implement my own timeout queueing contraption for this.

I was aiming for being able to write something like the following code:

function bubble ()
{
    for (var i = array.length - 1; i != 0; --i)
    {
        for (var j = 0; j != i; ++j)
        {
            if (less (j + 1, j))
                swap (j + 1, j);
        }
        mark_as_done (i);
    }
    mark_as_done (0);
}

Looks pretty straight-forward, doesn't it? One just needs to write less(), swap() and mark_as_done() to change/animate certain SVG objects, and it's all done, right? Well, I'm certainly no Javascript wizard, so that's what I thought too.

However, since JavaScript is not run in a thread separate from the browser, you can't just implement animation by modifying values and wait()'ing for a couple of milliseconds. In fact, it turns out, there's no explicit way to wait for a given time at all. What you can, and should, do, is set up a callback to be executed after a certain amount of time. The JavaScript API for this is a function called setTimeout(), and there's also a separate function called setInterval() that sets up the callback to be run every n milliseconds.

The APIs are string-based, that is, callback functions and arguments are passed as JavaScript text. That alone calls for some quite un-intentional coding, for example, check out the source code for this SVG file:

function start_animation()
{        
    setTimeout("anim_down('subject', 10)", 25);
}


function anim_down (id, n) { var elem = document.getElementById(id); translate (elem, 0, 10);

if (n) setTimeout("anim_down('" + id + "'," + (n - 1) + ")", 25); else setTimeout("anim_left('" + id + "', 20)", 25); }

As you can see, it's a pain in the ass to make sure everything is nicely representable as a string -- e. g., XML element ID's are passed around instead of pointers to the actual elements. But you can always store state in some global variable, that's not the real problem. To see what the problem is, try clicking repeatedly on the button and see how the animation gets deformed. It's not hard to guess what's happening: a second timeout-cascade is set up before the first one had time to finish.

So in the bubble() function defined above, all swapping animations would start simultaneously. And there's no way to select() or join() or whatever until a certain timeout has run. We need to create a timeout queue.

Look at the code below for a minimalistic approach. Timeouts that register timeouts themselves should set/clear current_timeout, like in this example.

var timeout_queue = [];
var timeout_queue_timeout = 0;
var current_timeout = null; 
var timeout_queue_freq = 100;


function pop_timeout () { if (!timeout_queue.length) { clearInterval(timeout_queue_timeout); timeout_queue_timeout = 0; return; } if (!current_timeout) { var timeout = timeout_queue.shift(); timeout.run (); } }

function queue_timeout(timeout) { timeout_queue.push(timeout); if (!timeout_queue_timeout) timeout_queue_timeout = setInterval("pop_timeout()", timeout_queue_freq);

pop_timeout (); }

Try clicking multiple times in quick succession in the second example: you won't see any corruption in the animation this time. Also, if you look at the code, thanks to the pseudo-synchronization, the animation can be expressed more intentionally:

function start_animation()
{
    animate('subject', 0, 10, 10);
    animate('subject', 10, 0, 20);
    animate('subject', 0, -10, 10);
}
25 Nov 2005 (updated 25 Nov 2005 at 20:11 UTC) »
Porting Guikachu to Windows

After surveying what needs to be done to get Guikachu on Windows, it turned out it's not going to be a difficult task. The only libraries that are not readily available for MinGW are libgnomeui, gnome-vfs and GConf. Of these three, making libgnomeui and GConf optional is straighforward, but Gnome-VFS is used throughout the IO code, which in turn is used throughout the whole codebase.

So what I first did was creating new implementations of load_uri/save_uri that use POSIX open/read/write/close calls.

Then I looked at GTKmm for Windows. At this point, I should point out that GTK+ doesn't work on Windows 98. It would have saved me a lot of frustration, have I known this in advance.

All in all, the port is coming along nicely, with some ugly hacking inside Automake-generated Makefiles, I've got it to compile today. It still has problems at link-time, however: ld is complaining about missing VTables of some GTKmm classes. I hope to sort these out by tomorrow.

Update: It's alive! (click here for screenshot)

NULL vs 0 in varags

Last week I got a weird bug report about Guikachu segfaulting at startup in g_object_newv, on AMD64. My friend Ice hooked me up with an account on an AMD64 box so I compiled a library stack with debug symbols, and it turned out the crash originated from gnome_program_init, which is declared as following:

GnomeProgram *
gnome_program_init (const char *app_id, const char *app_version,
                    const GnomeModuleInfo *module_info,
                    int argc, char **argv,
                    const char *first_property_name, ...);

This forwards the vararg list to g_object_newv which basically works like this:

prop_name = first_property_name;
while (prop_name)
{
    GType type = lookup_prop_type (prop_name);
    val = va_arg (vararg, type); /* Of course this doesn't really work like this, 
                                    there's a huge switch() block hidden beneath macro magic */
    set_prop (prop_name, val);

prop_name = va_arg (vararg, char*); }

So far so good, right? Well, gnomemm, which is a C++ library, calls gnome_program_init as such:

GnomeProgram* pProgram  = gnome_program_init (app_id_, app_version_,
                                              module_info.gobj (),
                                              argc, argv,
                                              GNOME_PARAM_POPT_TABLE, options,
                                              GNOME_PARAM_POPT_FLAGS, flags,
                                              0);

Looks harmless, doesn't it? The problem is, while in C++ 0 is used for NULL, in the above code the compiler has no way of knowing what 0's type above should be. So it goes with 'int', which is a reasonable default. This (int)0 eventually gets to g_object_newv, which reads it as a char*, and tries to see if it's NULL.

Now here comes the tricky part: remember, we're on amd64, so sizeof (int) == 4, but sizeof (char*) == sizeof (void*) == 8. So when va_arg (vararg, char*) reads the last property name, it gets 32 bits of zeros, and 32 bits of garbage. Resulting in a char* of garbage, which then gets passed to lookup_prop_type. Which makes baby Jesus cry.

So the moral of this all is:

  1. varargs are evil.
  2. varargs are even more evil than they look at first sight
  3. when using varargs from c++, make sure you use something like (void*)0 instead of vanilla 0 to denote a null pointer
  4. Have I mentioned how varargs are evil?
Guikachu

I've more-or-less finished the new Menu Editor for Guikachu. The items and submenus can now be reordered via drag & drop, and the preview area shows what the menu will look like on the Palm device.

GTKmm

After a very very long time, I've spent some time on GNOME's #c++ iRC channel in the last couple of days. It's great to talk to Murray again. As for great returns, I do plan to take up again writing Advogato entries regularily, if for nothing else, than to improve my English :)

I Was a Celebrity Star Guest

On saturday, I went to my old high school to present the awards for the winning teams of the regional round of the Bolyai Mathematics Competition. That may sound like I've become some sort of celebrity, but the truth is I was asked to do this only because I went to the school on the previous monday to retrieve my tent which I left there in the summer, and I met the headmaster who was just looking for old students having some connection to mathematics. When he asked me, I thought the competition would be in-house, with ten or so kids, but it turned out to be a regional round, and quite the event, with about two hundred kids aged 11-14. It was fun.

Holidays

Going on trips is something that's been sorely lacking from my life these last years.

So, from sunday, three days at the Hungarian spa city of Hévíz was exactly what the four of us (Edina, Milan, his fiancee, and me) needed: we did nothing all day but sit in the thermal pools, eat out, and drink wine. Here are the photos.

And next weekend, I'm going to Krakow for three days, with four friends.

lost+found

Identifont: This clever site asks you a series of questions about the look of a typeface, then presents you with a handful of possibilities.

Creating your CV via XSL:FO

As promised, here's a step-by-step guide for using simple XSLT templates to create your resume in HTML and PDF from a common XML source.

Guikachu: New menu editor

With valuable input from GNOME's #usability iRC channel, I am now implementing this UI for Guikachu's menu editor. A key point of the interface is using D&D for reordering menu items. This requires me to write my own Gtk::TreeModel, which is soomething not really documented. It's coming along nicely: I've got it mostly working, only the implementation of the D&D interfaced needs some cleaning up.

As an interesting coincidence, several threads have started these last weeks on the GTKmm mailing list by people who are implementing their own TreeModels.

Maybe it's the new fashion.

TrueType fonts with FOP

I spent last weekend learning XSL:FO, so I can generate an online HTML version and a printable PDF version of my CV from a single source. I'll describe process itself in detail later this week.

I use Apache FOP to process the XSL:FO document into a PDF file. However, it has some severe limitations and even in my one-day trip to the world of XSL:FO, several of those have bitten me. One especially bothering problem was some glyphs getting smashed together when using TrueType fonts. I've found no mention of this problem on the web, so I thought I'd publish the workaround for this here: just remove the kerning information from fop-ttfreader's output. I used the following XSLT for this:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="kerning"/>
</xsl:stylesheet>

Note: I don't know if the actual bug is in TTFReader (i.e. if it calculates wrong kerning information) or in FOP's usage of the kerning values.

My Preciousssss...

On Tuesday last week, It was found. I was too busy studying for the surgery final (I got a B today), but Dad rang me up claiming to have found just the car we're looking for. I checked the classified and indeed it was the real thing: a 2 year old Miata 1.8 Sport, deep blue in color, with less than 7000 kilometers on the odo (it was used as a demo car). Thursday found us on our way to Göttingen, a trip of 1200 km. By Friday noon, all the paperwork was done and I was driving my Miata home. It happily went to 220 kph on the German motorway, but the noise was terrible -- this is no grand tourer.

Here's a photo I took while stopping at a gas station. With a fuel tank of only 45 liters, it was something I had to do a lot :)

The less exciting part of the story is that after I parked it at home, I had to realize that I have to recover the two days' worth of studying. So the car has been parked for an entire week now, but the waiting was killing me! To make matters even worse, the weather turned real nice and sunny in the last couple of days -- perfect roadster weather...

Mozilla Extensions

I've been using Galeon 1.2.7 since ages. It's based on the Mozilla 1.2 engine. The reason for using such ancient software is simple: Galeon 1.3 lost a feature I extensively use, namely, that Ctrl+click on any image saves it locally, without any hassle of popping up a directory selector or anything else. Like a picture? Just ctrl+click it and you know it's safely stored away.

So I decided to try writing that feature as a Firefox extension, to facilitate my migration to a browser that's more 2005 than 1995.

First of all, either there's no reference documentation for the interactions between the extensions and Firefox, or it's hidden too damn well. I found some tutorials in your average lame blogs to get me started, but those didn't link to the reference docs either. So I looked at existing extensions to figure out ways to do stuff.

The extensions, you see, are written in JavaScript. Yes, you read that right. Modern and robust on one hand, powerful and expressive on the other. Not. And judging by the 2-3 extensions I looked at, they are written by exactly the kind of people you might imagine writing JavaScript code.

Really, it was a race to see if I can code this damn thing before my brain melts. You can judge the result here.

XSLT over-engineeredness

An actual template I wrote for http://cactus.rulez.org/:

  <xsl:template match="external">
    <xsl:variable name="apos" select='"&apos;"'/>
    <xsl:variable name="uri" select="concat ($apos, '../', @href, $apos)"/>
    <xsl:variable name="expression" select="concat ('document(', $uri, ')/', @xpath)"/>
    <xsl:apply-templates select="dyn:evaluate($expression)"/>
  </xsl:template>

Actually it might not be so bad if it worked properly with namespaces, but of course it doesn't: since @xpath is evaluated as a simple string in the context of the template, you have to use the same namespace prefixes in the pages you write and in the template. Hmmm, DV, if you're reading this, I hope you have a trick up your sleeve to solve this...

Japanese Contemporary Film Festival

Tamás and I watched several Japanese movies at a small festival.

Suit Yourself or Shoot Yourself: This was actually a series of two comedies, both about a pair of petty criminals trying to keep afloat while crossing ways with the Yakuza. The two episodes were mostly the same, in fact, the plots were too much alike, and the jokes were sometimes too sparse.

Shangri-La: I had high hopes for this, being directed by Takeshi Miike. It delivered, but in a totally unexpected way: it looked more like a Kustorica movie set in Japan: Miike's trademark gore was nowhere to be found, instead, it felt like watching a fairy tale, set in the self-organizing society of homeless people with a heart of gold, deciding to help a bankrupt contractor.

9 Souls: This one was terrible. Started out to be a violent, grim comedy, but instead, it turned into a cliché-ridden, pretentious snorefest taking itself so seriously, I had to laugh out during certain 'artsy' scenes. We weren't even one hour into it when I started looking at my watch in 10-second intervals, waiting for it to finally end. Avoid.

Hotel Hibiscus: advertised as "an adaptation of a comedy manga showing the world, and Okinawa, from the viewpoint of a 9-year-old girl", I was afraid it would turn out to be too sweet for my teeth. Instead, it was really magical and beside having great gags, it simply made everyone in the audiance feel good -- a perfect ending for the festival, and just what we needed to erase the horrible memory of 9 Souls.

Thesis

I've uploaded it here, but you shouldn't bother, because a, it's in Hungarian, b, it's some totally specialized radiology stuff. But if you do look at it, try to find the easter egg...

Check out this awesome game quiz (page is in Hungarian, but just fill in the forms with the titles of the games). It took three of us to complete it, but it can be done.

139 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!