Flow 07: Sunday and Regina & Husky Rescue at the Huvila Festival Tent

Sunday was a whole lot better at Flow than Friday. Everything worked better and the music was lovely. Kudos to the organizers for seeing the problems and acting to correct them.

Highlights:

  • Risto is the king of the world.
  • Tuomo played just the kind of music you'd love to hear on a sunny Sunday afternoon.
  • Korpi Ensemble was easygoing and fun.

On the not quite as good front, it was the first time I had heard of Jenny Wilson and wasn't really very impressed. Nice enough, but didn't really generate any strong feelings. Bebel Gilberto was better, but she arrived late on the stage and I don't think she really captured the audience. We left in the middle of her set.

Monday evening we went to see Regina and Husky Rescue at the Helsinki Festival Huvila Tent. Both were excellent, even though Regina would have clearly worked even better in an envinronment where people wouldn't have been sitting down — the tent doesn't really encourage you to move your ass.

All in all, you get the feeling that Finnish music is doing pretty well.

Article page

Flow 07: Friday done

First day of Flow is behind. This year, we bought tickets for Friday and Sunday, we'll skip Saturday. I have a few not-so-great photos online.

The good:

  • The artists. Pepe DeluxĂ© was good, sometimes great. Terry Callier was brilliant. No complaints about the other stuff, but those were the only two complete sets we heard. Well, CocoRosie was, er, slightly too weird for my tastes.
  • The location, the old Suvilahti power station. The outdoor space isn't quite as excellent as last year, but it is pretty nice anyway. And even closer to home. And having the club space in the same place justifies the move pretty well.

The bad:

  • Queues. Queues everywhere. One of the main attractions of Friday for us was Nicole Willis and The Soul Investigators. We spent the time they were on stage in the line outside the festival area, waiting to get in. Partially a timing problem (starting the first set at six o'clock on a Friday evening is just too early), partially a organizational problem (why does it have to be so slow to let people in?) Time to get a beer from the bars next to the main stage: 20-30 minutes. And of course the bar areas are fenced and you aren't allowed to go buy your drinks from another bar and take them to the main stage. Queues to the toilets, too.
  • The main reason causing the queues: too little staff. They would have probably doubled their sales if there was actually enough people staffing the bars. When they opened the club space, there was apparently one person staffing the three bars, serving a couple of hundred potential customers.
  • No schedules anywhere. If you didn't print out the schedule yourself, too bad.
  • Too small venues. The main stage was ok and we didn't really go to the club hall except right when it opened, so no idea how that was later on. But the tent where The Five Corners Quintet, Jukka Eskola, The Stance Brothers and Timo Lassy were the last acts was woefully small, with horrible crowding. We couldn't stand it so had to skip them, which meant that with Nicole Willis missed earlier, we didn't see half the acts we were trying to see.
  • The hot dog stand ran out of buns before hotdogs and gave out all the hot dogs to people when there were still others in the line. Thanks. We would have paid for those. After that, the only food left was a small piece of dry lasagna costing ten euros. This looks like a pretty good business.
  • The beer was Fosters. The cider was Upcider. The wines were JP Chenet.

If we hadn't already bought the tickets for Sunday, we might seriously reconsider our plans: good music, but they made it way too difficult to enjoy it.

Article page

Slightly disappointed in Nemerle

I've been coding with Nemerle a bit during the last couple of months. I've discovered that I had set my expectations too high. It doesn't quite live up to them. Might be as much my fault as Nemerle's, but that doesn't really change anything.

I was hoping for a experience closer to OCaml (only with better cross platform library support) than I got. With OCaml, once your code compiles, you know you are doing pretty good. With Nemerle, not so much. First of all, it feels like you get to fight a bit more with the type inferer than in OCaml. This is probably partially due to the maturity of the implementation, partially due to the fact that with OCaml, I didn't use as serious class hierarchies as I do with Nemerle, thanks to the .NET standard library and heavier Gtk+ usage.

The second problem I've encountered is that when you interface a lot with C# code, you don't really get much mileage out of the functional stuff in Nemerle. When you have a List generated in C#, you don't get to fold over it. While Nemerle does have the ICollection interface extending System.Collections.Generic.ICollection with all the functional iteration tools, there are no wrapper classes and no standalone functions. If you want a foldable List, you'll have to copy stuff. Not nice.

And third, while the variables are by default non-mutable, which is nice, and when you define your types in Nemerle you can do matching and get the safety that brings, you end up interacting so much with .NET code that you have to do the normal null checks all over the place anyway.

In short, the benefits of Nemerle over the current features of C# are feel pretty limited. Maybe it would be better if you were working with pure Nemerle projects, but at least interacting with C# eliminates most of them.

Article page

Making Emacs understand ncc errors

Add this to your .emacs or equivalent to make Emacs' compilation-mode make proper links out of the Nemerle compiler's error messages:

(setq compilation-error-regexp-alist 
    (append compilation-error-regexp-alist 
            '(("^\\(.+\\):\\([0-9]+\\):\\([0-9]*\\):\\(?:[0-9]*\\):\\(?:[0-9]*\\):" 
            1 2 3))))

Update:

Or even better, using rx (thanks to this hint for reminding me about it):

(setq compilation-error-regexp-alist 
      (append compilation-error-regexp-alist 
              `((,(rx line-start 
                      (group (1+ (not (any ":"))))
                      ":" 
                      (group (1+ digit)) 
                      ":" 
                      (group (1+ digit)) 
                      ":" 
                      (*? digit) 
                      ":" 
                      (*? digit) 
                      ": ") 1 2 3))))
Article page

C# export for Gaphor

Gaphor is the best free UML tool for X I've seen yet. It's far from finished but at least it produces pretty graphs. I started writing a C# export plugin for it. The first somewhat working version is available. This has been developed with 0.10.4, no guarantees of it working with any other version. No guarantees of it working with that version either, to be exact, but at least it works for me.

Extract it inside Gaphor's source directory, in gaphor/data/plugins.

Article page

Python, Queue, Pygame and the GLib mainloop

The GLib mainloop is what you're probably running in your Python program when you are using PyGTK or GStreamer.

Sometimes you want to integrate other event sources to it. The documentation for this is a bit thin; all I've seen is GLib's page on the main event loop, GSourceFuncs section and test-source.py in pygobject. Here I'm presenting two snippets displaying how to do it with two systems I've needed to work with. No guarantees on their correctness, but they do seem to work. Both are parts of larger modules, so they aren't usable by themselves and aren't really tidied up to look like proper examples. However, they should give you the general idea.

Here's how to do it with Python's Queue:

class QueueSource(gobject.Source):
    def __init__(self, queue):
        gobject.Source.__init__(self)
        self._queue = queue
        self.logger = loghelper.get_logger(self)

    def prepare(self):
        return False

    def check(self):
        return not self._queue.empty()

    def dispatch(self, callback, args):
        self.logger.debug("dispatch called, callback: " + str(callback))
        if callback is not None:
            self.logger.debug("dispatch calling callback: " + str(callback))
            v = callback(self._queue.get(), *args)
            self.logger.debug("dispatch returned " + str(v))
        return True

    def finalize(self):
        self.logger.debug("finalize called")


m = QueueSource(self._queue)
def my_callback(command, *args):
    self.logger.debug("my_callback: args: " + str(command) + ", " + str(args))
    self.logger.debug("my_callback: thread: " + str(threading.currentThread()))
    if command == self.PLAY:
        self._player.play()
    elif command == self.STOP:
        self._player.stop()
    elif command == self.SKIP:
        self._player.skip()

m.set_callback(my_callback, mainloop)
m.attach()

And here's Pygame:

class PygameEventSource(gobject.Source):
    def __init__(self):
        gobject.Source.__init__(self)
        self.logger = loghelper.get_logger(self)

    def prepare(self):
        return False

    def check(self):
        try:
            pygame.event.pump()
            p = pygame.event.peek(
                [KEYUP, KEYDOWN, VIDEOEXPOSE, VIDEORESIZE, NUMEVENTS, QUIT,
                 ACTIVEEVENT, USEREVENT])
            return p
        except Exception, ex:
            self.logger.error("Caught an exception while checking for events",
                              exc_info=True)

    def dispatch(self, callback, args):
        if callback is not None:
            try:
                e = pygame.event.poll()
                v = callback(e, *args)
                return v
            except (KeyboardInterrupt, SystemExit):
                self.logger.warn(
                    "Caught a terminating exception while dispatching to the "
                    "callback, re-raising", exc_info=True)
                pygame.display.quit()
                raise
            except Exception, ex:
                self.logger.error(
                    "Caught an exception while dispatching to the callback",
                    exc_info=True)
        return True

    def finalize(self):
        pass

def my_callback(self, event, *args):
    if event.type == QUIT:
        sys.exit()
    if event.type == KEYDOWN:
        self.logger.debug("my_callback: keydown: event.key: " + str(event.key))
        if event.key in (K_q,):
            sys.exit()
        elif event.key in (K_n, K_SPACE):
            self._player.skip()
        elif event.key in (K_p,):
            if self._player.playing:
                self._player.stop()
            else:
                self._player.play()

    return True


def start_mainloop(self, mainloop):
    self.logger.debug("Starting mainloop")
    if not self._started:
        s = PygameEventSource()
        s.set_callback(self.my_callback, mainloop)
        s.attach()
    return
Article page