Thursday, March 4. 2010
LinkedIn phishing vulnerability Posted by Troels Henriksen
in DIKU at
15:47
Comment (1) Trackbacks (0) LinkedIn phishing vulnerabilityThe popular social networking site LinkedIn suffers from a phishing vulnerability that makes it possible to take control of another persons account. In particular, it is possible to silently attach an additional email address to another persons account, then use that email address to reset the password and obtain full control of the account. This requires nothing more than the owner of the other account agreeing to establish a connection. The procedure is as follows:
The vulnerability lies in step 3, in that the victim is never informed that a hidden piece of information (the email provided in step 1) will be attached to their profile. While not strictly a technical problem, the phishing vulnerability is based on an implementation that does not make the consequences of user actions explicit, and which embeds potentially harmful information in a seemingly innocent link. Problems such as these are every bit as important as a buffer overflow or XSS-vulnerability, and should be guarded against just as vigilantly. This vulnerability was discovered (and tested!) on a grey afternoon by Martin Dybdal, Ulrik Rasmussen, and myself. Saturday, January 16. 2010Comment (1) Trackbacks (0) Den Datamatiske DevolutionI datamaternes tidligste tid interagerede man med dem ved at ændre dem direkte: Ved at indstille kontakterne på deres kontrolpanel kunne man kommunikere med dem i deres eget sprog, i den materielle struktur som udgjorde deres egentlige eksistens. Så fik man præcise og veldefinerede skriftsprog, hvor alt havde en veldefineret og kontrolleret mening: Der var yderst få tvetydigheder, meningen blev bestemt og veldokumenteret af centrale administrationer, og det var muligt at kommuniker effektivt og præcist med datamaten, så snart man havde investeret en moderat mængde tid i at sætte sig ind i konventionerne. Med tiden steg mængden af disse skriftsprog eksplosivt: Hver datamat havde sine egne kommunikationsregler, ja visse enkelte installationer afviger endda drastisk fra deres naboer, og det kan være utroligt svært at vide hvordan kommunikationen skal foregå, med mindre man kan spørge en lokalkendt om råd. I 80'erne og 90'erne udviklede man for alvor musen og de grafiske brugergrænseflader, hvor man nu måtte udtrykke sin mening med mere eller mindre vagt kropssprog. Nu hvor talegenkendelse er ved at slå igennem er vi endelig nået mod slutpunktet for devolutionen indenfor grænseflader: Som jeg har illustreret ovenfor er vi indtil videre gået modsat evolutionen for menneskeligt talesprog, og derfor er vi snart reduceret til at pege og grynte ad datamaten for at bibringe vores intentioner. Hvis idéen med passive, allestedsværende, indlejrede enheder ("pervasive computing") virkelig slår igennem vil vi endda afvikle os til et punkt hvor vi slet ikke kommunikerer med datamaten længere. Det tog os millioner af år at bevæge os den distance med menneske-til-menneske-kommunikation! (Omend det naturligvis var i den anden retning.) Monday, July 14. 2008SkønlitteraturI de seneste par uger har jeg genopdaget en interesse som jeg har forsømt i alt for mange år - læsning af skønlitteratur. Derfor er jeg gået i gang med at indkøbe og læse en serie af fantasy-romaner skrevet af min yndlings fantasy-forfatter, Raymond E. Feist. Hans historier, som tager deres begyndelse med Riftwar-serien, er især værd at læse fordi de forstår at kombinere det fantastiske med det hverdagsagtige, på en måde så det fantastiske ikke bliver dagligdags og derved uinteressant. Tolkiens bøger er baseret på samme koncept, men sætter dog også et relativt lavt loft over omfanget af supernaturlige fænomener, hvor Feist nærmest har gjort en sport ud af at gøre den lejlighedsmæssige magiske indblanding mere og mere ekstrem. En anden ting, der gør Feists bøger interessante, er at de tilsammen dækker en meget lang tidsperiode (over 100 år) i hans fiktive verden; man følger derfor hovedpersoner vokse op, ældes, få børn og dø af naturlige (eller unaturlige) årsager, hvorefter deres børn tager over. Det giver verdenen en atmosfære af realisme at de mange store begivenheder således kan spredes over en længere periode, i modsætning til visse andre langvarige fantasy-serier som lader til at have potentielt altødelæggende katastrofer hvert andet år. Friday, June 27. 2008Haskell og DebianTilbage i 2007 var mit nytårsforsæt at lære Haskell. Eftersom jeg skriver om det nu, må det vel antages at det ikke blev opfyldt, hvilket er korrekt. Dog er jeg nu begyndt at rette op på det ved at læse lærebogen Programming in Haskell og løse Euler-problemer. Lærebogen er ganske udemærket, dens eneste brist er at den ikke forudsætter nogen form for forgående programmeringserfaring og således bruger en del sider på at beskrive grundlæggende programmeringskoncepter (og bogen er ikke for tyk til at begynde med). Det lader til at være et generelt problem med mange af de funktionsorienterede sprog: Stort set alle tilgængelige bøger er lærebøger beregnet til helt nye programmører, en situation hvor Common Lisp, der har mesterværker som Art of the Metaobject Protocol, skiller sig noget ud. For at opnå erfaring med brug af Haskell i rigtige projekter er jeg gået over til en ny window manager, xmonad, baseret på den tese at jeg vil blive så irriteret over diverse ubekvemmeligheder at jeg bliver motiveret til at ændre i koden. Der er allerede adskillige ting der irriterer mig (først og fremmest de elendige genvejstaster, et punkt som ratpoison har forvænt mig med). Jeg er også begyndt at overveje at droppe Debian som styresystem til fordel for Ubuntu. Min oprindelige argumentation for at bruge Debian var at det ville være lettere at vedligeholde Debian end at tilpasse Ubuntu til mine til tider usædvanlige præferencer. Efterhånden er jeg begyndt at tvivle på dette, især efter mit system er begyndt at nægte at vise output på både laptop-skærmen og den tilsluttede VGA-skærm på samme tid. Friday, June 6. 2008Terroristerne kommer!Som de fleste vel efterhånden er klar over var der for et par dage siden et selvmordsangreb på en dansk ambassade i Pakistan. Siden da har medierne været fyldt med artikler og ledere om at Danmark har overstrukket sig selv og nu er blevet et terrormål helt på højde med Storbritannien, USA og Israel. Lad os betragte den handling der affødte dette hysteri. Det var et terrorangreb, jovist, men det fandt sted i udlandet, ingen danskere kom til skade og det skete adskillige år efter den gerning, som det angiveligt skulle hævne. Forstå mig ret, jeg mener ikke at terrorangreb bliver mindre afskyelige af at der ikke er dødsfald i min egen klub, men det virker nærmest respektløst at sammenligne dette med de voldsomme angreb som er sket på Storbritannien, USA og Israel. På sin vis minder det om borgerkrigen i Afghanistan, hvor vi hver eneste gang en dansk soldat mister livet, får at vide at vi er ved at tabe krigen og ikke er i stand til at føre den. Det synes jeg igen er en forvanskning af sandheden. Betragt krigs--statistikkerne: De danske tropper og deres allierede mister voldsomt færre mænd end deres fjender, og i forhold til tidligere krige er den materielle og personalemæssige investering minimal. Selv Danmark har personligt ført væsentligt større krige i vor fortid, og dengang var vi langt fattigere og fåtallige end nu. På nuværende tidspunkt er vores indsats i Afghanistan, samt terror-"truslen", langt mere baseret på politisk vilje end egentlige militære og sikkerhedsmæssige overvejelser. Det virker mest af alt som et ønske om at slutte sig til de seje lande som virkelig er i fare for terrorangreb, men i sidste ende er det bare patetisk. Saturday, May 24. 2008#:els:2008I have just returned home from the European Lisp Symposium of 2008, held in Bordeaux, and I shall now inflict upon you my experiences from the event. I'm not a very experienced traveller - indeed, this was my first time travelling by plane by myself, so I was slightly worried about getting lost along the way from Copenhagen to Bordeaux. My trip was fairly uneventful, though I was a bit mystified by travelling via a KLM-owned Fokker 100, a plane manufactured by a company that left the business quite a while ago. I was not less mystified when the rest of the flight was done in a plane that the safety guide claimed was a Fokker 50, but which most assuredly did not have turboprop engines. For my part, the stereotype about French people not understanding English turned out to be fairly true. Even more, the tram ticket machine did not understand English either, the clearly labelled button for changing the interface language seemed totally nonfunctional, as if it was literally just painted on the machine. I was told that the attitude towards English had changed in France - I can only imagine it has changed from open disdain to a feeling of irrelevance. Anyway, on to the interesting part: the actual symposium, which spanned over two days. The first day contained confusingly named "Birds of a feather" sessions (also known as workshops/discussion sessions). They were quite interesting, though I admit I had too little interest in parallel programming to be that aware during the first session. The CLIM/ McCLIM session was interesting, though my own part in it was pretty much a disaster due to my SBCL session getting totally messed up in some way. Scott McKay (the original designer of CLIM) managed to inject some interesting comments though. Amusingly enough, it did not seem like he had the same vision for CLIM as I have now, and rather took great pride in how the spiritual successor (DUIM for Dylan) could perfectly resemble a mainstream, native user interface. The informal session about the eventual successor to ASDF was perhaps the most interesting, some actual and involved discussion ensued and Nikodemus came up with the idea for a clever/horrible reader macro that inspired the title of this blog post. It seems like the ASDF successor will be motivated by two main things: facilitating a sane ASDF-Install replacement and elegantly handling weird compilation options. Exactly what I need, so I won't complain. I may even contribute code if it comes to that. The presentations were decent, but I found that I learnt more interesting stuff by talking with the authors than by listening to their talks, so I'll elegantly skip to perhaps the most important thing about the meeting: talking to other Lisp programmers in real life and finally meeting people I've talked to online for years. It was very educative and entertaining; from listening to Scott McKays view on CLIM, to discussing more general programming with Christophe Rhodes and Robert Strandh, to getting a primer on Finnish politics by Nikodemus Siivola. I obviously can't give a comprehensive description of every topic touched by these conversations, but I can encourage anyone who has never been to one of these events to attend the next possible one, since actually talking face to face allows some discussions to work much smoother than they do online. Unless practical problems get in the way, I'll definitely be attending the next European Lisp Symposium. It was certainly a very rewarding investment of my time. Monday, May 12. 2008VoxelsTænk tilbage på de tidlige halvfemsere, tilbage til 3D-computerspillenes barndom. Dengang var 3D ikke nødvendigvis lig med polygoner, sådan som de er nu, i stedet var voxels (3D-pixels) en yderst realistisk mulighed. Som alle ved vandt polygonbaserede spilmotorer stort, hjulpet godt på vej af hardwareacceleration, men voxels har stadigvæk en fordel i kraft af deres fleksibilitet og gode understøttelse for kurvede overflader. Et blik på hvordan 3D i stedet kunne have udviklet sig kan man få ved at prøve Voxelstein 3D, et kort skydespil der bruger en voxelbaseret grafikmotor. Den vigtigste voxel-egenskab dette spil demonstrerer er hvor relativt nemt det er at lave spilområder som kan ødelægges - hvad der er yderst kompliceret med polygoner er trivielt med voxels. Jeg synes selv at det er interessant, men det er næppe overraskende at jeg er interesseret i halvdøde og obskure teknologier der påstår at kunne gøre alting bedre end det, der nu er mainstream. Wednesday, April 23. 2008Comment (1) Trackbacks (0) McCLIM 0.9.6, day of the lizardslayerMcCLIM 0.9.6 "St. George's day" has just been released (Andy Hefners suggestion of "Discovery of the AIDS virus day" was not used), with quite a number of features. It's been over half a year since the last release (which is unfortunately pretty typical for McCLIM), so here's a list of the major improvements:
To celebrate this release, I hacked together a simple Logo
interpreter. The cool thing about this interpreter is that it
abuses Pen Up Lock To "Draw Left Half-Circle" Repeat 18 Forward 10 Left 10 Next End To "Draw Circle" Invoke "Draw Left Half-Circle" Invoke "Draw Left Half-Circle" End Unlock Pen Down Center Repeat 36 Invoke "Draw Circle" Forward 20 Next I'm not going to tell you what the output looks like, instead you
can download McCLIM 0.9.6, load tortoise.lisp and use
Tuesday, April 1. 2008Den moderne legendeDanmark har endelig fået sig en rigtig helt, en ambassadør for landet, en personificering af den danske ånd og kultur, som kan bidrage til at fremme vores respekt i udlandet. Jeg taler naturligvis om den fænomenale Martin, som jeg har fulgt på kanten af sædet i mange uger under det forløb hvor han udviklede sig fra en naiv, ung mand til den bastion af selvsikkerhed og karisma han udgør i dag. Det er måske ikke tydeligt ved første øjekast, men han er faktisk en historisk betydningsfuld faktor i dansk kulturhistorie - man opfatter ofte komponister som Beethoven og Mozart som altid at have fokuseret på den aristokratiske elite, men sandheden er at "klassiske" komponister blot var den tids pop-musikere - sandelig, det trak dem mere ned end løftede dem op, at den aristokratiske overklasse forsøgte at gøre dem til sine egne. I modsætning hertil er Martin nærmest demokratisk valgt, fælles for hele befolkningen, og begunstiget med et guddommeligt talent. Han har ingen af de klassiske komponisters svagheder, men alle deres styrker, så jeg forudser at man om århundreder vil se tilbage på 2008 som gennembrudsåret for den største danske musiker - nogensinde. Friday, March 28. 2008Se South Park online!Måske er jeg sløv som ind i helvede, men jeg har just erfaret at man kan se alle South Park-afsnit online. Idet South Park, især de tidlige sæsoner, er en af de bedste serier nogensinde, har jeg allokeret de næste par dage til at genopleve den del af min opvækst, og det samme bør du. Wednesday, March 5. 2008Dobbelt så godt!Der har været stille på denne blog i lang tid - nu vil jeg starte op igen med hvad jeg gør bedst, nemlig at brokke mig. I dette indlæg vil jeg kritisere vores kære statsminister, nærmere bestemt hans seneste nærmest tragikomiske besøg hos verdens cowboy, George W. Bush. For det første lader det til at Fogh opfatter Bush som en god leder af den årsag at han er en "flink fyr" som man "gerne vil drikke en bajer med nede på værtshuset" - en klassisk beskrivelse der åbenbart ofte bruges af den menige amerikaner. Jeg ved ikke om Bush er en sådan flink fyr, jeg ved ikke om han er god at tage på druk med - men jeg ved at det er totalt ligegyldigt for om han er en god statsleder, og jeg forstår ikke hvorfor det overhovedet er relevant at snakke om den slags ting. Jeg vil klart foretrække en usympatisk, ukarismatisk stivstikker af en politikernørd, såfremt han er kompetent, frem for et flinkt, men inkompetent, fjols. Det er grunden til at jeg normalt godt kan tolerere Fogh som statsminister, til trods for mine politiske uenigheder med ham. Hvad siger
Fogh ellers? Vi har bl.a Jeg mener, jeg er ikke engang synderligt liberal, og alligevel synes jeg den slags tricks er totalt vanvittige. I Danmark er det ikke gået helt så galt (endnu?) - vi er stadigvæk på det punkt hvor vi blot bruger tonsvis af penge på overvågning uden beviselig effekt, projekter der satser mere på at skabe en følelse af tryghed end egentlig sikkerhed. Bah, findes der overhovedet nogen lande i vesten der ikke er blevet grebet af denne tryghedssyge? Hvorfor er de ikke i Skandinavien? Vi skulle forestille at være et folk drevet af fornuft, rationalitet og gensig tillid... Friday, February 8. 2008Fakta
Tuesday, January 29. 2008Comments (0) Trackbacks (0) Unusual method combinations are your friend! Method combinations are one of the really cool, yet often
overlooked, parts of CLOS. They allow you to elegantly and succinctly
specify protocols that would otherwise require wrapper functions, ugly
calls to This kind of functionality is, I think, what makes Lisp a powerful language. Many other languages have syntactical shortcuts and convenient functions for everything, enabling very short programs that do interesting things (Ruby is particularly good at this). Common Lisp is not well suited for one-liners and very short programs, the syntax and provided facilities are usually too general. On the other hand, Common Lisp shows its power once the program grows - the language facilities are well suited for splitting up complex code and defining small ad-hoc frameworks (like generic functions with unusual method combinations) that would require a fair bit of code in other languages. Thus, I believe that while Common Lisp may look overly verbose for short programs, it makes it possible to implement long programs in a smaller amount of code than it would take in many other languages, and the resulting code can be flexible and extensible, even for complex problems. Sunday, January 20. 2008Comment (1) Trackbacks (0) A uniform macro for converting objects to other types A few days ago, the great topic of #lisp was type conversion
functions, and in particular the notation that should be used for
them. Some advocated As my focus was on ease-of-use, an intuitive interface and
predictable semantics, I decided that the overall pattern of
(<- (integer string) "123") => 123 (<- (integer string integer) 123) => 123 However, I didn't feel like it was "fully there" yet, as you might want to define a type conversion function like this:
(defun integer<-string (string &optional
(start 0) (end (length string))
(radix 10))
(values (parse-integer string :start start :end end :radix radix)))
I think you should be able to provide values for those optional arguments. And since I'm writing a type converter, it would be outright embarrassing if you had to provide those values directly, and couldn't convert them from something else - and why not integrate that directly into the single type-list (the first argument to the macro)? That is good program design, as it clearly puts all type-specifiers in a single place. This is now possible: (<- (integer (string integer)) 1 "123") => 23 (<- (integer (string integer integer)) 1 2 "123") => 2 (<- (integer (string integer integer)) 1 3 8 "123") => 19 As you may note, I decided that the arguments to the type conversion function should go before the actual object to be converted. This is good program design, as the overall macro works by first saying how to convert something, then providing the actual value(s). I think the same rule should count for the values. As an added bonus, it is now possible for machines and humans to perform sophisticated reasoning about the macro without looking too much at the type list, as you know things like "the second through to the second-last argument contains option values" and "the last argument is the value to be converted". You may note that the "real" order of types is preserved in the type list, that's because it's more logical that way. Also, you may argue that Lisp is about freedom, and my requirement to put parameter values first in the value-list conflicts with that ideal; but while Lisp is indeed about freedom, putting the value to be converted first is so plainly wrong that no-one would ever do it, or expect it to work. Is it really loss of freedom if you weren't going to (or weren't supposed to) do it anyway? But wait, there's more. I mentioned it would be embarrassing if you couldn't easily type-convert the optional arguments, so of course that was implemented too. When the type-list turns into an actual tree, the objects to be used are retrieved from the object-list as types are encountered in the tree during a depth-first search (and, of course, with the above-mentioned rule about the first type in a list, or the "target type", being selected last). So you can now write expressions like:
(<- (integer (string (integer string))) "1" "123") => 23
(<- (integer (string (integer string)) integer) "1" 123) => 23
(<- (integer
(string (integer string)
(integer (string integer integer integer)
integer))
integer)
"0" 0 2 2 10 123) => 12
The final example above truly shows the power of the <- macro. We have (are you ready for this?) an integer, 123, that is converted to a string. This string-conversion takes arguments, namely an integer that is converted from a string ("0"), and also (this is the big one) an integer 10, that is converted to a string, and then back into an integer starting from string offset 0, ending at 2, and in base 2 (the result is the integer 2, of course). Finally, the string (which is now "12") is converted to an integer, and the final result is thus the integer value 12. But of course, if you have nothing but an elegant and succinct notation, you end up with theoretical mathematics, and I'd like to take this type conversion utility a bit further than that. Thus it is useful to predefine a set of type conversion functions. I'd like to talk a bit about some of the more interesting of these. A very common task in modern programming is converting a bit-string
into an integer, this is done via the (defun integer<-binarystring (binarystring) (integer<-string binarystring 0 (length binarystring) 2)) Another useful conversion is integers to strings - in many other languages the null string, the string "0", the string "false" and others are all equivalent to the false value, while "1", "true" and the like are the true boolean value. I don't know why this feature isn't part of ANSI CL, but I suspect it may have to do with lack of time and resources on part of the standardisation group. But never mind that - while Lisp was not the first language to get an object system, it got the best one by far when it catched up. I was looking for something similar with this conversion function. There is a list of strings that are true ("true", "1", "correct", "proper", etc) and a list of strings that are false ("false", "0", "bad", "deficient", etc), but this alone is just slightly more comprehensive than most other languages, not in an entirely different league, as CLOS is when compared to other object systems. Lisp used to be an AI language, and therefore I felt it would be highly appropriate if this conversion function used intelligent, language-aware semantics as well as the plain list, and thus, it handles "in" and "not "-prefixed strings, meaning that the following useful cases work as one would intuitively expect: (<- (boolean string) "true") => T (<- (boolean string) "not true") => NIL (<- (boolean string) "not false") => T (<- (boolean string) "correct") => T (<- (boolean string) "incorrect") => NIL (<- (boolean string) "bad") => NIL (<- (boolean string) "inbad") => T Finally, I'd like to describe the "integer to boolean" conversion. Conformity with prior experiences, and the expectations that arise from these, are important when designing intuitive semantics, so I looked to what boolean values other languages attribute to integers. The generally accepted pattern seemed to be 0=false, 1=true, ..., so that is what I implemented: (defun boolean<-integer (integer) (not (zerop (mod integer 2)))) In conclusion, I think I fulfilled my initial design goals of intuitive semantics and a simple interface for the type conversion utility library. The source code can be retrieved here, but I'm going to submit it for inclusion into Alexandria in a few days, so you hopefully won't need to manually include the file in all your projects in the future. Wednesday, January 9. 2008Comments (9) Trackbacks (0) I can put *what* in my buffer?Hello, reddit! There's a link to a screenshot near the bottom, and as an extra treat, this is from my test of the new JPEG reading facilities in McCLIM: jpegsinclimacs.png As some of you may know, Climacs is an attempt at writing an Emacs-like editor in Common Lisp. This is obviously a hard problem that requires a lot of work - I have often been amazed at just how many exotic cases and conditions GNU Emacs handles in even simple editing functions. It is a very mature program, and it shows, while Climacs is still far behind Emacs in terms of functionality and stability. But while clever editing commands and similar things aren't that hard to implement - they mostly require time - most peoples initial impression of Climacs has been one of very bad performance, which is another class of problem entirely. Climacs was quite sluggish, even on fast machines, and it's quite understandable that most people didn't get a very good impression of a thin-featured program that was several orders of magnitude slower than Emacs. To rectify this, I have spent the last week and a half writing a new redisplay engine for Climacs (specifically, the editing substrate Drei). Performance is not yet as good as that of Emacs, nor as good as I would like it to be, but it's much faster than the old engine, and even more important, it does not get (significantly) slower as the size of the buffer increases, only the size of the actual displayed buffer region affects redisplay linearly. While doing research on efficient redisplay in text editors, I discovered that there isn't a lot of writing on doing this on a bit-mapped display with colours - I used an article on the Andrew text editor as initial inspiration, but it didn't cover everything I needed to do. Therefore, I'm going to write a bit about Drei's redisplay algorithm. The redisplay engine was developed based on a key assumption: output records are nice, flexible and useful, but they are too slow and heavy. Hence, the redisplay engine does not use output records, except for handling cursors and some other exotic situations. Instead, it divides the visible region of the buffer into strokes. A stroke is a unique buffer region (does not overlap with other strokes) that can be drawn in a single operation with a single set of drawing options, and that does not cross lines. Put another way, a stroke is a sequence of characters in a line with the same colour and font (strokes can also cover non-characters, but let's ignore that for now). The new redisplay algorithm thus works by fetching strokes from the buffer, starting at the top of the display, and drawing them to the screen until we reach either the end of the buffer or the bottom of the visible part of the output sheet. When strokes are drawn, we remember the location and size of their output. Due to the constraint that strokes cannot cross lines, we can trivially organise strokes into lines and just check for whether a stroke directly precedes a #\Newline character to figure out when we should go to the next line, and when we do this, look at the strokes of the line and figure out the dimension of the line. Additionally, we get the nice property, that when redisplay is finished, no two strokes overlap. Stroke objects are kept across display, and are mutated by the mechanism that retrieves strokes from the buffer (the stroke pump, see below), so we can easily check whether a stroke has changed (we mark it as "dirty" and "modified") since the last redisplay, simply by having the pump check whether it is going store already-existing data in the stroke object. If a stroke is obscured for some reason (for example due to a moving window, or part of the cursor being drawn over it), we also mark it as dirty. Taken together, this enables incremental redisplay, as we only redraw strokes that are dirty, and only recalculate their size if they are modified. The interesting problem is now how to generate strokes for the redisplay engine. This is done through two generic functions, pump-state-for-offset and stroke-pump, that are used to "pump" stroke data into existing stroke objects. This is both to implement incremental redisplay, as mentioned above, and to avoid consing (if you read the code, you'll notice that I've been obsessed with minimising consing in general, perhaps this was not always necessary). For the most common case, these functions just relay to the syntax of the view, which results in either the simple stroke pumping defined for Fundamental Syntax, or a general parse-tree walker defined for LR syntax that can select drawing colours based on the actual parse symbols (wrapped in some macrology, syntax highlighting rules can then be defined like this). There is nothing special about stroke pumping, except that it has to be really fast, as it is completely non-cached and done in full for every redisplay. All the clever caching and "only handle that which has actually changed"-stuff is done at the higher level by looking at the dirtiness of strokes, and at the lower level by the incremental syntax parsers. The stroke pump just has to be fast, something that is most efficiently done by connecting it closely to the parse information. When the view is a pure buffer-view (that is, has no syntax) there is a simple fallback pump defined that just turns each line into a stroke (possibly chopping it up if it's very long), it's not fast, but it's simple, and you can look at it to get a general idea of how it works, if you're curious. It's defined in drei-redisplay.lisp As an interesting special case, and as hinted at by the title of this post, strokes do not have to cover sub-strings of the buffer. For each stroke we have an associated set of drawing options, and in addition to holding colour and font information, it also contains the function to be used for drawing the stroke. Commonly, this is the default function, which copies a string out of the buffer and prints it with the function draw-text*, but if a sufficient function is provided, any Lisp object can be drawn. Indeed, Fundamental and Lisp syntax recognise non-characters in the buffer, and create single-object strokes, with a special drawing function, for these. This function presents the object, via CLIM, and draws the resulting output record. This means that any Lisp object can at least be displayed as if by print-object, or if a CLIM presentation method has been defined, as pretty much anything. This screenshot demonstrates the feature. Of course, stuffing the buffer full of arbitrary objects can still fail badly in other ways, as not all editing commands know how to deal with it. In conclusion, if you were previously put off by the poor performance of Climacs, you should give it another try. It's not near Emacs speed yet, but it's quite usable on modern machines, and should improve further in the future (compared to the old redisplay engine, the new can actually be further developed and optimised in a straightforward way). There's also a pretty low barrier-to-entry for hacking, and lots of low-hanging fruit still. Tuesday, January 1. 2008Godt nytår anno 2008!Nu er det så 2007 år siden der skete noget ingen ved om rent faktisk skete for 2007 år siden, da de historiske kilder er mangelfulde og modstrider hinanden (og ja, jeg mener 2007 år, vi gik fra år 1 før, til år 1 efter, der har aldrig været et år 0). 2007 har været et godt år, men det har ikke forhindret mig i at fucke mine nytårsløfter totalt op, idet jeg først kom i tanke om dem for et par uger siden:
Jeg har bl.a. fejret nytåret ved at læse denne frygteligt underholdende rant hvor Ruby on Rails-samfundet bliver kaldt grimme ting. Jeg kunne naturligvis her skrive et afsnit om hvorledes Lisp-samfundet er Ruby-samfundet klart overlegen, men da jeg ikke har personlige erfaringer med sidstnævnte ville dette være usædvanligt usagligt, selv for denne blog. Thursday, December 27. 2007Comments (2) Trackbacks (0) Structedit: Paredit clone for ClimacsFor some time now, I have been using Paredit for editing Common Lisp code in Emacs (if you don't already, you should start too!). It's a highly useful approximation of an actual structure editor, with the important detail that it modifies the files just as a sequence of characters, putting intelligence into the editing commands rather than the data structure, and so works perfectly with all the tools that expect flat character files. While I can't claim to write much code with Climacs, whenever I do, I am annoyed by the lack of Paredit. Thus, I spent some time implementing a preliminary version of a Paredit clone for Climacs (named Structedit, as I want to emphasise the similarity to proper structure editors). It is not a perfect clone, apart from being far less full-featured and tested, it implements a few facilities slightly differently from Paredit. The base is (or should be) the same, however While hacking out the code, I performed a number of observations:
Structedit requires the newest CVS-version of McCLIM, and its commands are not yet as comprehensive as those of Paredit, so use at own risk. If you're feeling adventurous, try hacking in some missing functionality (C-k is a bit bare-bones, if you need a starting point); it shouldn't be too hard. Monday, December 24. 2007Comments (0) Trackbacks (0) Den er ornlig syg den julNu er det igen, og over hele landet, med tidsforskydning endda over det meste af verden, samler folk sig for at fortære det nærmest rituelle juleådsel og udveksle de ejendomme der strategisk er blevet placeret under fremtidens træflis. Jeg har selv tænkt mig at deltage i denne seance med glæde og uden protester, til trods for at jeg hverken er kristen eller udpræget stor tilhænger af traditioner for traditioners skyld. Alligevel er jeg tilhænger af julen, fordi den fungerer som en socialt veletableret undskyldning for at være social og arrangere traditionelle sammenkomster (såsom de famøse julefrokoster). Det kan godt være at julen når man anskuer den objektivt er helt forfærdelig - en gammel vintersolhvervsfest forvansket af den katolske kirke til et meningsløst sammensurium af hedenske og kristne symboler og traditioner, der totalt har mistet enhver forbindelse til den oprindelige idé bag dem. Senerehen er julen så blevet overtaget af kommercielle interesser, og nærmest blevet et monument til vestlig forbrugsmentalitet. Men til trods for at julen således er dybt korrupt rent filosofisk, fungerer den stadigvæk som en undskyldning til at gøre, og arrangere, ting der opfattes som gode eller hyggelige. Og måske opfatter jeg kun traditionel juleudsmykning som behagelig fordi jeg under min opvækst blev hjernevasket af forbrugssamfundet, men i så fald bærer jeg intet ønske om at ophæve denne selvillusion - verden er kun som vi opfatter den, og der er næppe årsag til at gøre vores opfattelse mere deprimerende eller negativ end den allerede er. Jeg vil forbigå diskussionen omkring de betydelige udledninger man kan drage fra forgående sætning, og i stedet ønske alle læsere af den nye bibel en glædelig jul, og opfordre jer til at undersøge for jer selv hvor lidt kristendommen egentlig har at gøre med den moderne juletradition. Monday, December 10. 2007Comments (2) Trackbacks (0) Views in Climacs - gratuitous complexity ahoy!Some time ago, Robert Strandh proposed to change Climacs by moving away from the classic Emacs concept of operating on buffers, and insert a middle layer of objects called "views". I just spent the two weeks implementing his ideas in Drei and Climacs itself, prompting me to write this blog post. So, presuming you care about Climacs, why should you care about views? What problem do they solve. To put it in somewhat simplified terms, the problem with the Emacs buffer/mode-concept is that a single buffer can only be in a single major mode (called "syntax" in Climacs parlance) at a time, and any enabled modes is an intrinsic quality of the buffer itself. This prevents some neat programs from being written (more on this below), and prevents the user from having a buffer displayed in two separate windows with two different rules for syntax highlighting. Of course, this is a rather dubious usage scenario, so let's grab hold of a concrete problem views solve for Drei (the editing substrate behind Climacs). Essentially, Climacs had a very ugly problem, wherein commands making multiple operations on a buffer had to call the function update-syntax to make sure the syntax parse tree was up to date with the buffer contents - failure to do so could cause commands to behave strangely (as with the Indent Region-command before it updated the syntax after indenting each line) or crash outright, as with some of the more complex commands in Lisp syntax. So, easy solution: make syntax functions call update-syntax themselves to make sure they always operate on, or return, up-to-date information. Well, not so easy as it seems, as the only place a description of buffer-changes, since the last syntax-update was performed, was stored, was in the buffer object itself, and update-syntax would overwrite this information with a "no changes" flag, which might not be expected by other pieces of code interested in when the buffer changes. To be fair, some Emacs-style hacks could have been implemented, buffers could have been tied inseparately to their chosen syntax, and we'd end up with something usable. But the pain this would bring if we want to do more complicated things with buffers and syntaxes (like having two windows displaying the same buffer of HTML code, one showing syntax-highlighted raw code, and the other showing a rendered WYSIWYG version) made this seem like a really bad idea. With views, the syntax is not an intrinsic property of a buffer, rather it is a property of a specific view of a buffer, and a buffer is not specific to anything, except the Climacs instance itself. The new buffer-modification-protocol enables views to register themselves as observers of a buffer object and be notified whenever changes happen, with a description of what part of the buffer was modified by the changes. The view can then maintain a clear picture of how much of the buffer changed since the views internal data structures were last synchronised to the actual buffer contents (for a typical view, this will be a parse tree based on some grammar). Whenever a view is asked to do something (like, redisplay itself on a pane) it will synchronise itself, using its stored information about buffer changes to figure out which parts of its data is outdated and needs to be brought up to date. In Climacs, views are dealt with in approximately the same way as buffers - you use C-x C-b to change between them, C-x k to kill them, etc, but there are some minor differences, in particular because a view cannot be displayed in more than one window at a time (in contrast to Emacs buffers). An interesting consequence of views is that there is no rule for how a view of a given buffer should be presented - the obvious way is of course to show the contents of the buffer coloured to fit some provided syntax scheme, but an interesting alternative is to show a more high-level interpretation of the buffer contents. For instance, this file defines a view displaying the definitions of a Lisp buffer of some other view (screenshot of incestuous use here), with each definition being a clickable hyperlink to its location in the buffer (this is CLIM, after all). The view is automatically updated whenever the buffer contents change, removing a lot of the tedium of writing somewhat interesting views. Of course, there's still problems: the Climacs UI is not really geared to deal with so unusual views yet, and the two views both maintain their own parse trees of the buffer, despite the fact that they're equivalent. Some optimisation is probably in order here. Of course, Drei, Climacs and McCLIM has slightly more pressing needs than the implementation of whimsy views of dubious utility, so it is unlikely this particular situation will improve significantly any time soon. Sunday, December 2. 2007PrinsenJeg er blevet færdig med at læse en af mine fødselsdagsgaver - Fyrsten, en bog skrevet af Niccoló Machiavelli for henved 500 år siden, så nu besidder jeg al den boglige viden der skal til for at være renæssancefyrste i Toscana (bogen genopvækkede også min Europa Universalis III-besættelse). En bemærkelsesværdig ting ved Fyrsten er hvor pragmatisk, ja man kan vel næsten sige rationel, den er. Der bruges meget lidt tid på etik og moral, i stedet gives en række benhårde råd til hvordan man skal vinde, sikre og bevare magten - og det virker ikke som om Machiavelli's råd var udpræget kontroversielle for sin samtid, hvor selv en mafioso ville opfatte dem som afstumpede og koldhjertede. Det er jo ikke en nyhed at verden, eller i hvert fald Europa, i almindelighed er blevet mere fredelig end den var i renæssancen, og når man læser en bog som Fyrsten får man også det indtryk at menneskelig sindsstemning har ændret sig voldsomt meget. Det kunne være interessant at vide om den gennemsnitlige Europæer for 500 år siden ikke ville have de store skrupler over at handle efter Machiavellis råd, eller om indtrykket af tidligere tiders grusomme kyniskhed udelukkende skyldes at de eneste litterære overleveringer vi har fra de tider er forfattet af herskere og folk i nærheden af magten. I dag er stort set alle i stand til at forevige deres meninger og oplevelser, så hvordan mon fremtiden vil se på vores etik om endnu 500 år? Vil de opfatte os som amoralske barbarer, eller vil de erfare at menneskesind er konstante over så korte perioder, og at alt der ændrer sig er samfundsmiljøet? Det er jo desværre et spørgsmål jeg nok aldrig får svar på. Friday, November 23. 2007Comments (0) Trackbacks (0) Tillykke med fødselsdagen!Hejsa Troels fra fremtiden! Tillykke med de 20 år! Jeg er Troels fra fortiden - helt præcist, den 9 juli 2006, og dette er en tidskapsel. Nu er du gammel og svag, mens jeg endnu er ung og viril - føl min spot og min hån. I dag har jeg været frygteligt uproduktiv - mine CVS-redskaber fucker op (igen), og jeg har opdaget at Homeworld II slet ikke er så fedt endda. Men jeg må nok hellere smutte omgående, jeg har en masse jeg skal nå før jeg bliver dig. Monday, November 19. 2007FagbøgerEfter jeg startede på DIKU har jeg bemærket en meningsforskel på mig og de fleste andre studerende - hvor der for andre nærmest er sport i at købe billige, evt. brugte, lærebøger, og skrotte eller sælge dem igen så snart kurset er afsluttet, har jeg en helt anden holdning. Jeg køber altid mine bøger som nye, helst som hardcover, jeg installerer dem i mit lille fagbogs-bibliotek når kurset er overstået, og jeg kunne ikke forestille mig at sælge bøgerne igen (måske med mindre jeg fik så meget for dem at jeg kunne købe nye udgaver). Selvom det naturligvis til tider er smertefuldt, med de uforståeligt høje priser der er på de fleste lærebøger, så har jeg en filosofi om at holde så meget af min viden på bogform, så jeg teoretisk set kan gendanne min fulde faglige viden, fra et hvilket som helst tidspunkt, udelukkende ud fra mine bøger. Udover at jeg således kan gendanne min faglige kunnen, såfremt jeg skulle miste hukommelsen (måske et noget søgt argument), føler jeg mig også sikret at jeg i hvert fald kan udbedre enhver regression i min faglige kunnen, og hvis jeg er usikker på noget jeg har lært, til enhver tid kan slå det op. Internettet er selvfølgelig også en vigtig kilde til læring, men jeg foretrækker at lære fra fysiske bøger, frem for elektroniske kilder, og ikke kun fordi jeg ikke bryder mig om at læse længere tekster på en skærm: Bøger er langt mere håndgribelige og varige, hvorimod elektronisk lagret data, især hvis det kun er tilgængeligt via Internettet, er væsentligt mere flygtigt, og kan ændre sig, eller forsvinde, til hver en tid. Dette ødelægger hele formålet med mit ønske om at samle al min viden på bogform, som jo netop er total sikkerhed for at jeg altid kan genopfriske hvad jeg har lært. Friday, November 9. 2007ValgplakaterEt valgkampsaspekt, som jeg virkelig ikke forstår, er den gamle tradition for valgplakater. Tidligere var de måske nødvendige for at formidle kandidater, tidspunkter for valgmøder og lignende, men allerede for 50 år siden burde radio og TV have overflødiggjort dette - og sandelig, de fleste, for ikke at sige alle, valgplakater prydes udelukkende af partiets navn og billede og navn på en én kanditat (for Enhedslistens vedkommende endda kun førstnævnte). Jeg kan til nøds forstå behovet for valgplakater til lokalvalg hvor ikke alle kandidater kendes af den brede befolkning, men jeg ser ikke behovet for valgplakater prydet af Helle Thorning-Schmidts ansigt, og mere generelt kan jeg ikke tro at en valgplakat kan påvirke nogens stemme. Hvordan skulle ræsonnementet være? "Jeg stemmer på den hvis ansigt jeg sidst så!" "Jeg stemmer på liste X, for de har penge nok til at tilklistre hele mit lokalområde!" "Jeg stemmer personligt på Anders Fogh fordi han ser så beslutsom ud på sine valgplakater!" Det virker mest som om valgplakater bare er en måde at motivere de ungdomspolitiske afdelinger til at mobilisere for at få sat dem op, og således højne deres moral gennem politisk relevant arbejde, men det virker stadigvæk som noget af en søgt forklaring. Thursday, November 1. 2007Comments (0) Trackbacks (0) Digitale miniatureblikkenslagereFor nogle måneder siden skrev jeg om Dwarf Fortress, et suverænt computerspil der kort forklaret er et roguelike strategispil. Forleden udkom der en ny udgave af spillet, den første i mange måneder og med en passende nye features og rendyrket awesomeness. De to primære features der har været hypet under udviklingen (mest af spillerne, programmøren er imponerende behersket) er tilføjelsen af en Z-dimension, således at man kan bygge i højden og dybden, samt en rigtig model for væskeopførsel - tidligere var vand og lava tilføjet via noget af et hack, men i den nyeste udgave fungerer de som man ville forvente væsker ville gøre (dog uden tryk, alt er tyngdekraftbaseret). Dette, sammen med Z-dimensionen, giver ufattelige muligheder for at bygge kreative konstruktioner. Dwarf Fortress har for en stor del altid handlet om at bygge avancerede fæstninger, og de nye faciliteter gør dette mere interessant end nogensinde før. Udover at der nu er mulighed for at lave fælder med lava der falder fra loftet, et gulv der forsvinder og afslører et dybt fald ned i et hul fyldt med pigge, eller diverse variationer over at drukne invasionsstyrkerne, er mulighederne for at lave et alment VVS-system i ens fæstning blevet kraftigt udvidede. Vand er, naturligvis, vigtigt - det kan drikkes (hvis man da mangler sprut), man kan få energi fra det via vandmøller, og det skal bruges til markdrift. Vand er samtidigt en noget besværlig ting at arbejde med - vandet i floden kan fryse til, og da det kun kan falde og flyde er det ikke altid ligetil at transportere det til hvor man har behov for det. Dwarf Fortress giver dog de grundlæggende værktøjer til at bygge løsninger på disse problemer, som regel i form af en stor tank (bare et stort rum der dækker flere Z-niveauer - spillet er tilhænger af generelle værktøjer) der ligger højt og som har diverse vandskakter og korridorer gående ud af bunden. Tanken fyldes så med pumper, evt. drevet via vandmøller i floden selvom arbejdsdyr naturligvis også kan bruges, og man har så højt beliggende vand der kan transporteres rundt i fortet som man ønsker, når man ønsker det. At udvikle effektive, fleksible og høj-kapacitets vandrørssystemer er i sig selv en fantastisk interessant, underholdende og tilfredsstillende del af spillet, og når det så kombineres med hvordan det spiller ind i en større helhed med fortets almene drift, bliver det jo nærmest helt perfekt. Alt i Dwarf Fortress virker logisk (eventuelt) - det er det ultimative sandkassespil, i stedet for at give spilleren en masse specifikke værktøjer får han nogle generelle som han så selv kan udnytte til specifikke formål. Dwarf Fortress er stadigvæk nærmest uhyrligt svært at lære, men det er det værd. Det tegner til at blive noget nær det suverænt bedste computerspil nogensinde. Wednesday, October 24. 2007Folketingsvalg anno 2007Så er der udskrevet valg - noget før tid, men det skyldes jo nok at diverse udøvende magter har fået kolde fødder over situationen i den lovgivende magt. Dette bliver den første afstemning jeg deltager i, så jeg har tænkt mig at gøre hvad jeg kan for at lave en så informeret beslutning som muligt - jeg har tidligere fortalt om hvordan jeg ikke vil lade mig binde af partimæssige tilhørsforhold, og jeg har derfor i højere grad tænkt mig at se på de individuelle partiers valgløfter (naturligvis modereret med deres track record for tidligere løfter) og så stemme på dem der for tiden, i dette valg, passer mig bedst, i stedet for blot at støtte det parti der alment bekender sig til en ideologi der ligger tæt på min. Mine forhåbninger, som jeg ikke forventer bliver indfriet, ville være noget i stil med at Venstre og Dansk Folkeparti mistede indflydelse. Hvis vi fortsat skal have en borgerlig regering vil jeg klart foretrække at den er konservativt domineret, da jeg efterhånden fuldstændigt har mistet respekten for Venstre og deres populisme - de konservative har jeg langt mere respekt for, og alt hvad jeg har set og hørt tyder også på at de fører politik baseret på hvad de mener er det bedste for Danmark, dvs. politik baseret på intelligens og ideologi (at jeg ikke er helt enig i deres ideologi er naturligvis relevant). Venstres formand, derimod, udtrykte i sin tid at man skal lade være med at høre på eksperter (denne form for anti-intellektualisme hører ikke hjemme i et land som Danmark, i mine øjne). Det er jeg klart overbevist om er en rigtig dårlig idé. Hvad Dansk Folkeparti angår synes jeg blot at deres politik (især den økonomiske) generelt er for kortsigtet, og naturligvis at deres ideologiske grundlag er primitivt og følelsesladet. |
Language selectionFoobar (EN)
My name is Troels Henriksen, known as Athas in some parts of the Internet. This is my weblog, where I write about everything and nothing in particular. I am, at the time of this writing, a student of datalogy at the University of Copenhagen. I spend my free time programming, mostly in C++ and Common Lisp. CalendarArchivesQuicksearchCategoriesCreative CommonsSyndicate This Blog |
All original material on this website is copyright Troels Henriksen, and may only be used in accordance with the license listed in the sidebar.
