pozorvlak: (Default)
Wednesday, November 3rd, 2010 07:12 pm
Today I have
  • Submitted some more documentation patches for Idris.
  • Written a fragment of the Unix tool cat in Idris:
    eachLine : (String -> IO ()) -> File -> IO ();
    eachLine f file = do {
    	finished <- feof file;
    	if finished then return II -- II is the sole element of the unit type ()
    	else do {
    		line <- fread file;
    		f line;
    		eachLine f file;
    	};
    };
    
    main : IO ();
    main = do {
    	file <- fopen "fred" "r";
    	eachLine putStrLn file;
    };
    You'll notice that the file to catenate is hard-coded: I haven't yet worked out how to access your program's command-line arguments.
  • Started work on a SEKRIT WEB PROJECT for some friends; however, so far all my time has been spent mucking about with configuration files and installing dependencies rather than actually coding.
    pozorvlak: (Default)
    Tuesday, November 2nd, 2010 02:25 pm
    Today's hack is up. It's to the flashlight app again; now the UI stays in portrait orientation no matter how you rotate the phone. This prevents the pause/resume/create cycle that was killing my Activity and causing the light to go out. Most of yesterday's code is no longer needed and has been taken out again, but that's a good thing, right? :-)

    Sideload the app (if you care - HTC Sense has such a thing built-in) from here.

    Anyway, the way you do this is by adding the attribute android:screenOrientation="portrait" to the activity element in your manifest. This tip came from this StackOverflow post: I tried the more complicated "add a configChanges attribute and override onConfigurationChanged" approach described there, but that resulted in the LED wedging in whatever state it was in when you rotated the phone and not accepting any further changes. God knows what was going on there.

    By the way, does anyone use git add -p much? I tried the "edit this hunk" feature a couple of times, but it told me that it my patch wouldn't apply cleanly, and then rejected the whole thing. Also, I'm having trouble uploading files to GitHub's "download" section.

    Edit: and I've had a documentation patch accepted into Idris. Go me!
    pozorvlak: (Default)
    Monday, November 1st, 2010 01:41 pm
    As seems inevitable these days, a load of my friends are doing National¹ Novel Writing Month this year. I won't be joining them: I have no particular ambition to become a novelist. However, I do want to become a better programmer.

    To that end, I shall be participating in my own Personal Code Writing Month, the rules of which are
    1. Write some non-work code every day.
    2. Make what I write available, if only on GitHub.
    3. Wherever possible, make something that can be used over the Web, and get it hosted somewhere so people can use it.
    I'm deliberately not setting myself a more concrete project or Grand Lofty Goal, for fear of scaring myself off: the idea is just to work on whatever attracts me on any given day. Nor am I setting myself any targets as to how much code I must write on any given day, or how long I should spend on it. To start with, though, I was thinking I might do something about the poor Factor coverage in the Programming Languages Examples Alike Cookbook, and I've just subscribed to the PLEAC mailing list.

    I'll be posting regularly about this: if you don't want to hear about it, please let me know so I can set up a filter or something.

    Edit: I've uploaded today's hack - a partial fix to the irritating "light goes off when you rotate the phone" bug on my LED flashlight. It's not a complete fix, because the light still blinks out for half a second before coming on again. I'm sure the world doesn't need Yet Another Flashlight App, but I'll sort out Android Market access and upload it there anyway. Meanwhile, you should be able to sideload it from here.

    ¹ By the way: why "national"? I see from Wikipedia that the first year (1999) was San Francisco-only, but from 2000 onwards it's been an international event.
    pozorvlak: (Default)
    Thursday, October 28th, 2010 11:30 am
    I badly need some better strategies for making sense of large, twisty, underdocumented codebases.

    My current "strategy" is
    • grep for interesting words or phrases
    • find relevant-looking functions
    • look for their call-sites
    • look up definitions of other functions called in those sections of code
    • if I don't understand what a variable's for (almost certain) then look for assignments to it
    • once I've identified all the bits of code that look relevant, stare at them until my eyes cross
    • maybe put in a few printf's, try to make sense of the logs
    • enter procrastinatory spiral of despair
    • stress about losing job
    • make more coffee
    • repeat.
    What do you do?
    pozorvlak: (Default)
    Thursday, August 26th, 2010 03:32 pm
    A couple of days ago, Chris Yocum asked me to help him out with some OCaml code. He's learning OCaml at the moment, and thought he'd practice it by solving a problem he'd encountered in his research on early Irish law.

    In early Irish law, murder was punishable by a fine dependent on the status of the victim. Ten-and-a-half cows per king murdered (no, really!), five for a major nobleman, and so on. At one particular event, we know the total fine levied, but not the number of victims. Chris wanted to find out the range of possibilities. This is an example of the change-making problem: given small change of various denominations, how can you give your customer 73p? I most often encounter this problem with rugby scores: if Wales beat England 67 - 3 (I can dream...), then at seven points for a converted try, five for an unconverted try and three for a penalty, what might have happened?

    Be the change you want to make )

    All suggestions for improvement, as ever, gratefully accepted :-)
    pozorvlak: (Default)
    Tuesday, August 24th, 2010 06:10 pm
    I've updated the JSON utilities first described here. Changes:
    • jd outputs JSON, as it should really have done all along. It's now an even thinner wrapper around Makamaka Hannyaharamitu's excellent JSON module :-)
    • jf now has a -p option that pretty-prints its output directly.
    • jf can now handle several field specifiers at once, and preserves enough of the structure of the input to contain them all. Here's an example:
      $ curl -s -upozorvlak:<my password here> http://api.twitter.com/1/statuses/mentions.json \
      | jf -p user/name user/screen_name text
      [
         {
            "text" : "@pozorvlak I have to admit that if you have polymorphism then
                     things like +. are particularly pointless.",
            "user" : {
               "name" : "Christopher Yocum",
               "screen_name" : "cyocum"
            }
         },
         {
            "text" : "@pozorvlak Huh, I still like the safety that static typing gives you.",
            "user" : {
               "name" : "Christopher Yocum",
               "screen_name" : "cyocum"
            }
         }
      ... etc ...
      ]
      The XPathy syntax is due to Leon Timmermans.
    You can download the source or check it out from GitHub. All suggestions (or better, patches!) gratefully received.

    So, what else could I do to make these useful? One option would be to allow a wider range of XPath selectors - currently only the child axis is supported - but I'm not sure how to do that and preserve the structure of the input, which is essential for the kind of thing I use jf for. I could certainly document the programs better. For now, though, I think I'll email Makamaka and ask if he'd be interested in including jf in the JSON.pm distribution.
    pozorvlak: (polar bear)
    Monday, July 26th, 2010 06:32 pm
    I recently underwent a major personal technology upgrade.

    This was in two parts. The first was to buy a second-hand Kindle 2 which was being offered on a mailing list I read. I've wanted an e-ink device ever since I read about the technology in the blue-skies column of some computing magazine or other, and the legibility hasn't disappointed: reading on a Kindle is a positive pleasure, nothing like the tiring experience of reading a backlit screen. So far, though, I haven't used it as much as I'd thought I would. One of the main things I bought it for was reading scientific papers; while it's possible to read A4 PDFs on it in landscape mode, it requires a lot of scrolling, and referring back to something a page or two ago is a hassle. This wouldn't be a problem for novels, but I've got a lot of treeware novels I feel compelled to read first. Another intended use-case was for travelling (I always take too many, and simultaneously too few, books whenever I go anywhere), but the only trip I've made since buying it was a cycling-and-camping holiday round Orkney: not ideal for sensitive electronics.

    I'm experimenting with converting PDFs to .mobi using Calibre: we'll see if that fixes the excess-scrolling problem.

    The second part was an upgrade of my phone. Owing to years of inattention and a major Ugh Field, I was paying an embarrassingly high amount for a phone that just did the very basics: calls, texts, er, that's it. It had a camera, but getting photos off the phone was such a hassle that I rarely bothered to take photos. No Internet, no maps, nothing fancy. I didn't much miss mobile Internet at first, but I've been training myself not to wonder, and the lost opportunities to learn were increasingly starting to grate.

    So, I reasoned, I could either keep my existing level of functionality and pay a lot less for it, or I could pay a bit less and get a totally bitching-ass phone¹.

    Then I got very, very lost trying to find my way to a pub in an unfamiliar part of town without a map, and decided to go for the second option.

    So I screwed my courage to the sticking-place, walked into a phone shop, and asked to see their range of Android phones. The Android-versus-iPhone choice was very simple, since I have access to precisely zero devices capable of running iTunes². I didn't even consider a Symbian or Maemo phone, though perhaps I should have. I had a brief look at the HTC Legend and HTC Desire, but fell instantly in love with the Google Nexus One - it's basically the same phone as the HTC Desire, but with (IMHO) a slightly nicer case design and a noise-cancelling second microphone. Slightly less RAM, but then it doesn't have HTC's proprietary Sense UI (which I didn't want), so it gets on fine with less. And so, after a week of hassle with my previous provider to get my number transferred over, that was the phone I took home.

    "Phone"'s the wrong word, though: it's really a general-purpose portable communication, computation and sensor platform. Out of the box it was a street map, an email client, a news-and-weather feed, a camera, a calendar, an address book, a web browser and, yes, a phone; within the next few days it became a device for playing text adventure games, a weight-tracker, a compass, a hiking map³, a star chart, a device for recording my hikes and bike rides, a tricorder, an ssh client, a graphing calculator, and a spirit level. Yes, a spirit level. What would Robert Hooke think? Most recently, it's become a handy reference for arguing with climate change deniers, a facility which I have yet to use in anger.

    I've also been working through the Android development tutorials, which have really impressed me; so far, it looks like a very sane and well-designed platform, though my little netbook struggles rather with Eclipse.

    But I'm surely missing something. A device like this must be capable of things I can't begin to imagine. So, what else could I be making it do? For those of you with smartphones, what useful/surprising/cool apps have you found? Don't hesitate to mention iPhone apps: I can go looking for Android equivalents, or have a bash at writing my own.

    There's one thing my phone definitely can't do, though, and that's dissipate [livejournal.com profile] wormwood_pearl's envy³ - which was made even worse when we went round to visit friends a week ago and they both pulled out their new HTC Desires. I guess I know what I'm getting her for her birthday...

    ¹ Or possibly a totally bitching ass-phone.
    ² And then there's Apple's distinctly unsavoury management of the App Store, my fear of getting caught on Apple's Treadmill of Shiny, and my general preference for open systems over closed ones. Android's less open than it could be, but hell, give it time.
    ³ And jealousy; she's remarked a few times "I don't mind you spending time with your new girlfriend, but would you mind not stroking her in front of me?" I think she's only half-joking :-(
    pozorvlak: (sceince)
    Wednesday, July 14th, 2010 06:01 pm
    For her Master's research, [livejournal.com profile] wormwood_pearl has to analyse some video. Not that much video, in the scheme of things - a couple of hours in total - but she has to decide and note down what's happening in every one-second chunk of said video.

    Ladies and gentlemen, I give you the non-stop, fast-moving, white-heat world of SCIENCE!

    [The lab has licenses for some expensive-looking software that's meant to do this automagically and without human intervention, but needless to say it doesn't actually work.¹]

    So she asked me if it was possible to script VLC to play a video for a second, then pause for a couple of seconds (so she could update her spreadsheet), play for another second, and so on until the video finished. That way she'd (a) get accurate seconds, and (b) save lots of time that would have been spent clicking back and forth. I said "Er, yeah, probably".

    It turns out that recent versions of VLC do, in fact, have a nice-looking scripting infrastructure based on Lua, but I don't have, and can't install, VLC on my work machine. So (at [livejournal.com profile] addict_yin's suggestion) I tried it with mplayer instead, and after a bit of fiddling got it to work. The program's very simple, but it's possible that someone else has this need, so I thought I'd make it public.

    If you too need to play a video in pause-interspersed chunks (of any length you like!), you can download Sleepy here. Installation and use is very simple, and described (at least for *nix systems - let me know if you want to use it on Windows) in the README. It requires perl and mplayer, both of which are free and run on damn near anything. If you think you can improve it, please fork the GitHub repository (because all the cool kids are using GitHub these days, right?), and then send me a pull request. All comments and criticisms are welcome.

    Yes, this is all massive overkill for what's actually a very simple script :-)

    ¹ It could be worse. Apparently an important early experiment on foam formation required a grad student to make up a soap foam between two glass plates, put the assemblage on a photocopier, and then press "Copy" every few seconds for up to ten hours straight. As my friend Micah put it when telling this story, if a nodding bird could do your research better than you could, you've probably taken a wrong turn somewhere.
    pozorvlak: (Default)
    Tuesday, July 13th, 2010 04:39 pm
    It occurs to me that not enough people know about TeX's line-breaking algorithm.

    Take a paragraph of text; this one, for instance. Form a graph whose vertices are possible line-breaks, and whose edges are the words (and part-words, in the case of hyphenation) between two possible breaks. For instance, if your text is "Fred loves Wilma", then you'd have four vertices: the beginning, the space between "Fred" and "loves", the space between "loves" and "Wilma", and the end. You'd have five edges: "Fred", "Fred loves", "Fred loves Wilma", "loves Wilma" and "Wilma".

    Now, here's the clever bit: you decorate each edge with the "badness" associated with fitting those words onto a line, represented as a number between 0 and 10,000. There are various heuristics used to calculate this "badness" score, but basically it comes down to how much you have to squash or stretch the words and the spaces between them, plus extra badness penalties for hyphenation etc.

    Finding the optimal set of line breaks is now a simple matter of applying a standard minimum-weight graph-traversal algorithm. Some further cleverness brings the average-case running time for the algorithm down to linear, and the worst-case to O(n2).

    Theoretical computer science for the win.

    Unfortunately, TeX doesn't apply this algorithm to the problem of breaking paragraphs into pages, for (AIUI) historical reasons: the machines on which TeX was developed didn't have enough memory to hold more than one or two pages in memory at a time, and so had to write out each page as it was created. The page-breaking algorithm is thus local rather than global, and hence sometimes gives strange results. Wikipedia informs me that optimal page-breaking is NP-complete in the presence of diagrams, but in practice we efficiently find good-enough solutions to NP-complete problems every day, so I don't know why they're still using the local algorithm. Hopefully some TeXpert will pop up in the comments and enlighten me :-)
    pozorvlak: (sceince)
    Monday, June 28th, 2010 03:16 pm
    Yesterday I finally crossed off a to-do item that's been bothering me for twenty-one years.

    In Primary 4 I had an evil, horrible, hateful, permanently-angry teacher called Mrs Begg. I have no qualms about giving her real name, and even if I did, she's surely dead now. Mrs Begg had one of those rolling endless blackboards, and up the right-hand side she'd write a list of things to do. As soon as the first child finished the last task on the list, she'd add another one on the bottom. I, of course, was usually struggling along somewhere near the top of the list, not because the tasks were too hard (they weren't) but because the work was mostly boring and the volume of stuff I was supposed to get through was too dismaying.

    Then, one day, she pronounced herself more than usually dismayed with the slow kids, and wiped off a bunch of items from the list. Great! you might think. But you'd be wrong, because (a) I'd just been told in no uncertain terms that I'd failed, (b) the list still grew faster than I could keep up, and (c) there were actually some items on the wiped-out portion that I was looking forward to doing. When I got to them. Whenever that would be.

    In particular, one of the wiped-out tasks was to make one of those paper fortune teller things. As a result of the Bonfire of the Makework, I never learned how to construct one. I'm sure you can imagine the difficulties that the lack of this crucial skill has caused in my subsequent life.

    When I'm under stress, the image of this Sisyphean blackboard comes back to haunt me, and especially the task that I was supposed to complete - that I was looking forward to completing - but didn't. So on Sunday I decided to exorcise it once and for all, by sitting down and making a paper fortune teller. I was going to Google for some instructions, but then [livejournal.com profile] wormwood_pearl offered to use her Magical Girl Powers¹ and teach me how to make one. Turns out it's really easy: cut out a square of paper, fold it across both diagonals, open it out again, fold all four corners into the centre to make a square with half the area, fold all four corners of the new square into the centre to make another square with a quarter of the area of the original square, fold this third square in half lengthways, then stick your fingers into the folds. If that's not clear, there are, for the moment, diagrams on the Wikipedia page.

    Since I'm a geek, the fortunes had a programming slant. After spelling out your favourite programming language and choosing your favourite regular expression metacharacter, you arrive at one of the following four fortunes:
    • Your projects will all come in on time and under budget.
    • You will be assailed by numerous heisenbugs.
    • You will not write enough tests.
    • You will write a subroutine too cleverly, and later regret doing so.
    The first outcome, of course, is the Holy Grail (and seen about as often), and the rest are almost inevitable.

    The alert or clueful reader will have noticed that there is only one good fortune, and so if the name of the sitter's favourite programming language has the wrong parity they are denied any possibility of a good outcome. This illustrates the important lesson that, though many technologies may be good enough to succeed, a bad initial choice can scupper you entirely. But even if you choose a language with the right parity, you have only a 50% chance of a good outcome: this illustrates the fact that good technology choices are necessary but not sufficient to success - the skill and good taste of the implementing team are still critical. More devilishly, if I know a particular sitter's favourite programming language in advance I can deny them any chance of success (mwahahaha! The power, it is intoxicating) which illustrates the unfortunate truth that even a good team using the best tools is screwed if the client doesn't play ball.

    ¹ By which she meant the Magical Powers she has by virtue of being a Girl, not the Powers she would have by virtue of being a Magical Girl. If [livejournal.com profile] wormwood_pearl is a Magical Girl, I have seen no sign of it. Which is of course exactly what I would expect to see if she were a Magical Girl...

    *cue Bubblegum Crisis music*
    pozorvlak: (Default)
    Thursday, March 4th, 2010 01:56 pm
    As part of my preparation for the PASTA job interview, I spent some time refreshing my knowledge of basic compiler theory, and learning about some of the bits that I'd never really got my head around. Here, in the hope that someone else will find them useful, are the notes I took about parsing theory. They're loosely based on the Edinburgh lecture course on Compiling Techniques. You'll need to be familiar with the notions of formal language and formal grammar (links go to Sam Hughes' highly approachable introductions to the subjects); you'll also need to vaguely know what a regular expression ("regex") is, and to know that every classical regex (ie, one without backreferences) can be mechanically converted to a Deterministic Finite Automaton (DFA) that accepts exactly the same set of strings. All code is for illustrative purposes only and probably won't even compile.

    Nowe read on... )

    Comments? Corrections? Clarifications? Questions? You know what to do.
    pozorvlak: (Default)
    Thursday, February 18th, 2010 11:40 pm
    Monday will be my last day at Winterwell Associates. Apparently there's a recession on or something.

    Now, I have no doubt that I'll be able to fill up my Copious Free Time; I have a long list of neglected side-projects crying out for my attention. But food, lodgings and climbing gear don't come free in this imperfect world, and so I'm going to need to get another job at some point. This presents you, the employer on the look out for a bright, flexible, mathematically-inclined software developer, with an opportunity.

    Here's what I'm looking for:

    You are a small tech company full of bright, knowledgeable and skillful people. You're working on something cutting-edge. You're friendly, but nobody's scared to call anyone on their bullshit. That said, you know that everyone makes mistakes, and the important thing is to work out how to stop that mistake from happening again. Ever. And then stopping that entire class of mistakes from being made again. Hence, you're fanatical about automation, and particularly automated testing. You understand the strengths and weaknesses of unit and functional testing, use both appropriately, and architect your system to make both easier. You practice continuous integration (ideally, continuous deployment), test-first development, ruthless refactoring, iterative design, and code reviews. You don't have a standing-up meeting once or twice a week and call yourselves Agile. You have sensible (and frequently reviewed) coding and documentation standards, and actually stick to them. You understand the benefits of documented conventions. You value clear, intelligible code, and don't resort to hacks and spaghetti logic at the first hint of difficulty. You do not suffer from Not Invented Here syndrome, but you're not scared to reinvent a wheel if you've looked and it's really too square for your needs. You're not hung up on any particular technology, but you do a lot of your work in dynamic languages like Perl, Python or Ruby. Oh, and you do your development on Linux or at least OS X, because life is far too short to use Windows. You're either based in Edinburgh (or at least Scotland), or open to teleworking. You pay at least well enough to support two frugal people.

    Does any of this sound like you? If so, please have a look at my CV, and get in touch by any of the means listed thereon.
    pozorvlak: (Default)
    Sunday, December 13th, 2009 03:16 pm
    We've been using git for version control at work for the last couple of months, and I'm really impressed with it. My favourite thing about git is what might be termed its unfuckability: no matter what you do to a repository to fuck it up, it seems, it's always possible to unfuck¹ it, usually simply by keeping calm and reading the error messages. I've managed to lose data with an ill-advised git reset --hard, but that was before I knew about the reflog, and I've always been able to recover "lost" work in every other case. And then there's the rest: cheap local branching², the index, the raw speed, git-bisect, git-gui and gitk (which has rapidly become an indispensable part of my development toolchain)³.

    The merge algorithm pretty much Just Works: we get the occasional merge conflict, sure, but (so far) never without good reason. So I was surprised to learn (from Mark Shuttleworth) of a really simple case where git's merge algorithm does the Wrong Thing ).

    Bazaar obviously gets this right, otherwise Mark Shuttleworth wouldn't have written his post. Commenters there suggest that Darcs gets this right too, but after spending a while looking through the Darcs wiki I discover that I really, really can't be arsed to work out how to do the necessary branching to test it. Hopefully some helpful Darcs user (I know you're still out there...) will be able to post the relevant transcript in a comment. [Edit: I realised belatedly that you don't need branches for this. Transcript here.]

    Overall, I don't think this is a show-stopper, or even a reason to seriously think about switching to another DVCS, but it's certainly worth remembering and watching out for.

    ¹ Why yes, I have been watching the excellent Generation Kill. How did you guess? :-)
    ² If you're not used to systems in which this is possible, it probably sounds really scary and difficult, and like the kind of thing you'd never need or use. It's not. It's actually really simple and incredibly useful. The article that made it click for me, Jonathan Rockway's Git Merging By Example, is no longer online, but I'm sure there are equally good ones out there. You'll probably find Aaron Crane's "branch name in your shell prompt" utility helpful.
    ³ Just to clarify: I'm not saying that Your Favourite VCS sucks, or that it's impossible to get these features using it: I'm just saying that git has them, and they're really, really helpful.
    pozorvlak: (Default)
    Tuesday, November 17th, 2009 11:48 pm
    In a (probably futile) attempt to acquire Real Ultimate Power, I have been trying some Project Euler problems in Factor. Here are my first five solutions, along with my comments: I was going to post my first ten solutions, but this was getting too long.

    Spoilers herein, obviously.

    Problem 1 )

    Problem 2 )

    Problem 3 )

    Problem 4 )

    Problem 5 )

    Overall comments
    • The dev tools are nice, once you work out what everything's called - the debugger's called the "walker", for instance. I particularly like the way that the listener pops up a stack effect declaration in a minibuffer when you type in a word's name - since the conventions are strictly followed, this is often all the documentation you need. When you need more, it's easy to get help and see source code using the help and see words, or using the browser (Alt+B). I haven't yet worked out how to take best advantage of the editor integration, but I'm sure that will come.
    • For getting started, I found the Factor cookbook invaluable.
    • #concatenative is one of the friendliest tech forums I've encountered, and hands down the most helpful. In every case my (admittedly n00bish) questions were answered before I'd finished posing them.
    • I'm finding programming without variables to be really hard. Factor does have facilities for both lexically- and dynamically-scoped variables, but I've been mostly avoiding their use, on the grounds that I'll have to learn how to use the stack some time and I might as well do so now.
    Any comments or questions, on the code or the presentation, are very welcome!

    Edit: thanks once again to the members of #concatenative, particularly slava and erg, for comments on this post.
    pozorvlak: (Default)
    Sunday, September 27th, 2009 12:00 pm
    It occurred to me recently that programming comes in several flavours, and that how much I enjoy a programming task depends strongly on which flavour predominates. The flavours I've identified so far, in descending order of how much I like them, are the following:

    Data munging: You have a large mass of data in some fairly generic form, and must fold, spindle and mutilate it with well-understood tools to extract the information of interest to you. Writing Unix scripts is the classic example, but list manipulation in Haskell or Lisp and array manipulation in J or APL have this flavour too.

    Clever algorithms: You have some calculation or task to perform, and brute force has proved inadequate. Now you must apply the Power Of Your Mind to find a cunning and better approach. I haven't actually done very much of this stuff, but I have had to solve a couple of problems of this nature at my current employer, and have another one waiting for me on Monday morning.

    Twisty if-statements, all alike: You want to zom all the glaars, but only if (the moon's in (Virgo or Libra), unless of course the Moon's in Libra and Hearts are playing at home), or (the engine-driver's socks are mismatched xor (the year ends in a seven and the month contains an R)). And you meanwhile want to wibble the odd-numbered spoffles if the Moon's in Libra, Hearts are playing at home and (the year ends in a seven or the engine-driver has mismatched socks). The challenge lies in making sure you've identified all the exceptions and special cases, and in actually coding them up correctly. Not remotely elegant, but better than...

    Doctor X-style wizardry: Making a system do things that it was never intended to do. If you squint at the problem just right you have all the tools you need to do the job, sort of, but it's at best a witty hack and at worst a horrible bodge, and certainly not something you'd want to put much weight on. All non-trivial TeX programming has this nature. This kind of thing is quite fun when you're doing it as a joke or a proof-of-concept, but it's downright horrible when you need to do it to get something important done. But it's still far more fun than...

    API spelunking. You have a candle, a slice of cheese, and a pair of old boots. You need a fork-handle. Is it even possible to construct one out of what you have? Is there a chain of method calls and constructors that will lead you from what you have to what you need? And if you succeed in constructing your fork-handle, is it the fork-handle you need? Or some nearby, but completely inappropriate, fork-handle? This is in some sense dual to data-munging. The worst examples I've encountered have actually not been in relation to documented APIs (though try reading lines out of a zipped text file in Java, if you want to see what I'm talking about), but rather in large crufty systems with complicated and ill-thought out data models. The Law of Demeter addresses this problem, but I have yet to work on a project that sticks to it. I'd settle for some sort of coherence theorem, but that would require coherent API design, which is kind of the problem to begin with...
    pozorvlak: (Default)
    Friday, September 11th, 2009 08:17 pm
    Me: You know, we really want some way of representing this problem that lets us have WAAFs pushing markers around on a giant diagram to keep track of our state.
    Joe: Yeah. On green baize. That bit's important.
    Me: Or we could just get a full-sized snooker table for the office.
    Joe: And an office that's large enough to fit a full-sized snooker table in it.
    Me: I've worked in offices with table football tables, but never one with a snooker table...
    Joe: Or we could just move the office into a pool hall.
    Me: Yeah, I like it.
    Joe: How cyberpunk would that be? We'd be an AI consultancy based out of a pool hall!
    Me: I think we'd need at least one cyborg. Does anyone have a pacemaker?
    Joe: I've got a false tooth...
    Me: Is it Turing complete, though? It doesn't count unless you can play Tetris on it.

    ... and, not entirely coincidentally, we're both hiring and looking for a new office. As well as the web developer role listed at that link, we're also looking to recruit more NLP and machine-learning experts. Pool skills and cybernetic body parts not essential ;)
    pozorvlak: (gasmask)
    Saturday, July 4th, 2009 12:16 am
    By popular demand, a picture of Slava Pestov wailing on guitar:

    Slava Pestov wailing on guitar, in mid-air.


    NB: image may not actually depict Slava Pestov.

    Previously.
    pozorvlak: (Default)
    Friday, June 26th, 2009 12:02 am
    Hi, this post is about Factor, real Factor. This post is awesome. My name is [livejournal.com profile] pozorvlak and I can't stop thinking about Factor. Factor is cool, and by cool, I mean totally sweet.

    Facts:
    1. Slava Pestov is a mammal.
    2. Slava Pestov hacks on Factor ALL the time.
    3. The purpose of Slava Pestov is to flip out and kill people.

    Weapons and Gear:
    1. Concatenative (stack-based, Forth-like) language.
    2. Dynamic types.
    3. First-class functions.
    4. Object-orientation.
    5. Real macros.
    6. Batteries included.
    7. The listener: debugger/REPL/help browser/etc.
    8. Optimizing, self-hosting native-code compiler.
    9. Ninja stars.

    Testimonial:
    Factor programmers can kill anyone they want! Slava cuts off heads ALL the time and doesn't even think twice about it. The guys on #concatenative are so crazy and awesome that they flip out ALL the time. I heard that littledan was eating at a diner. And when some dude dropped a spoon littledan GC'ed every object in memory. My friend Mark said that he saw a Factor programmer totally uppercut some kid just because the kid opened a gl-window.

    And that's what I call REAL Ultimate Power!!!!!!!!!!!!!!!!!!

    If you don't believe that Factor programmers have REAL Ultimate Power you better git clone their repository right now or they will chop your head off!!! It's an easy choice, if you ask me.

    Writing OpenGL code in Factor:
    Step 1: Look for some Factor OpenGL documentation.
    Step 2: Fail to find any.
    Step 3: Get really super pissed.
    Step 4: Get some C++ OpenGL documentation instead.
    Step 5: Put something slippery on it, like butter or cream.
    Step 6: Bend it to fit (this is crucial).
    Step 7: Keep folded and insert into listener hard.
    Step 8: Push hard until you can't see it.
    Step 9: Wait.
    Step 10: Die.

    If you succeed, everybody will be like “Holy Crap!

    Update: by popular demand, a picture of Slava wailing on guitar.
    pozorvlak: (Default)
    Saturday, June 13th, 2009 12:33 pm
    Probably everyone who's spent more than five minutes working with web services and JSON has versions of these utilities. Here are mine.

    jd: JSON pretty-printer/dumper )

    jf: extract fields from (lists of) JSON objects )

    I gratefully acknowledge the generosity of my employers (for whom I do not speak...) for allowing me to release these programs despite them being written during work hours. Thanks!