A New Project: stark

« on Feb 26, 2013 »

I want to talk a bit about my new project. Stark is designed with one goal in mind: to be my personal assistant, wherever I am. Stark is a simple message-passing system of distributed services to perform a range of tasks across multiple devices coupled with basic natural language processing.

Stark in GTalk

Let's clarify this by providing an example. I open a chat window to stark and write "remind me in 10 minutes to take the pizza out of the oven.". In the meantime, I powered my computer off. Stark then informs me after 10 minutes by sending a notification to my smartphone. Another example: I tell stark on my smartphone to "play music by Faun on my desktop pc" and he complies.

By analyzing these examples, we can compile multiple requirements:

  • Natural User Interface (language recognition)
  • Works across multiple devices (PC, Smartphone, Cloud)
  • Has access to lots of tools (Music Player, Database, Time, ...)
  • Dynamic routing to the correct service/user

The project is currently in a mix of concept and prototype stage, a long time away from any real world application, but I hope it evolves over time.

Premise: A World of Computing

If the last decade was characterized by the rise of the internet, this decade is probably marked by the rise of mobile devices and ubiquitous computing. Most people have a smartphone today, permanently connected to the internet. The trend continues with the development of even more wearable tech, such as smartwatches (e.g. Pebble) or Google's augmented reality Project Glass. We have personal assistants (e.g. Siri and Google Now) that present information and perform tasks with simple voice commands. I expect that computers and the Internet become even more pervasive and a natural part of our lifes in the coming years.

Where does stark fit in?

Most of these devices and applications provide an API to control them remotely, but those are heavily fragmented. My desktop music player, MPD, has its own protocol. The music app on my smartphone can be controlled via Android Intents by other processes. My phone can accept notifications and files from the Internet (e.g. PushBullet), but my desktop pc cannot do the same without specialized applications and protocols. It becomes even more complicated if we want to combine two services ("send a notification to my smartwatch when the song on my desktop pc changes") - now we have to translate between two protocols.

Stark wants to abstract all these applications and protocols into yet another, unified, protocol. But this time standardized by me for my personal use. Instead of writing a remote music client, I develop a music "service" that listens for "play music" messages. On Android, this may use a music app - on my PC it may use MPD. Same for notifications - every device has a method to display notifications, let's make them available across devices via a simple "notify" message.

Architectural Overview

The tasks can be started by the user through multiple endpoint services: a chatbot, a commandline application or desktop launcher, a GUI or natural speech. Natural speech is parsed by a natural language processing service that can be situated anywhere in the network. Messages are routed over multiple protocols (TCP, HTTP, GCM or XMPP) and are delivered to the right service which performs the task and responds. In bullet points:

  1. User gives a command (text, speech, interface: "play music")
  2. Stark routes the message to a language recognition service
  3. The service extracts the right action and data to perform ("music.play")
  4. Stark routes the new task message to the service across devices (music player)
  5. The service executes the task (plays music)
  6. Optionally, the service replies or sends tasks to other services.

Example of topology

Under the Hood

Let's take our music example and see how stark processes it. Here, the user opens a terminal application that connects to the stark network via a local stark router on the desktop. The user enters "Stark, play music by artist Faun". Since the terminal is just a very simple wrapper around the network without any logic, it sends a "natural.process" message with the user command. It hopes that somewhere in the network is a service that understands "natural.process" messages and can translate them into the correct action to undertake.

{
    "action": "natural.process",
    "source": "desktop/terminal",
    "message": "Stark, play music by artist Faun"
}

Stark currently uses JSON as the underlying format, but this can be adjusted depending on the requirements of the underlying transport protocols.

The message is sent to the local stark router which, luckily, has an inbuilt service for natural language processing. It dispatches the message to this service which parses the command. It correctly identifies the action "music.play" and extracts additional metadata for the command ("artist": "Faun").
The natural service sends the new message back to the router, hoping some service can react to "music.play".

{
    "action": "music.play",
    "source": "desktop/natural",
    "data": {
        "artist": "Faun",
    },
    "reply_to": "desktop/terminal",
}

MPD receives the message since it supports "music.play". It checks for the "artist" metadata and plays the correct songs. To confirm that this was successful, it replies with another message, this time to the correct destination specified in reply_to: "desktop/terminal".

{
    "action": "notify.success",
    "source": "desktop/mpd",
    "target": "desktop/terminal",
    "message": "Done."
}

The terminal then simply prints the message "Done." for the user. Currently it is encouraged that each stark message contains a human-readable field describing it, but later it could be routed through a natural language generator.

Current State and Outlook

I have written a reference implementation in Go, consisting of libraries for services, router and the underlying connections. There is an example server available, as well as clients for terminal and XMPP which can connect over TCP or local channels. The spec is under constant evolution, so documentation is still missing in this early prototype phase.

There are a lot of directions in which to go. More supported transport protocols, additional services, better language recognition, implementations for other devices (escpecially Android apps). My next goal is to implement machine learning for language processing instead of static rules and to set a webserver up, so that stark can be permanently online.

package main

import (
    "github.com/xconstruct/stark"
    "github.com/xconstruct/stark/service"
)

func main() {
    serv := service.New(service.Info{
        Name: "hello",
    })
    serv.Dial("tcp://127.0.0.1")

    msg := stark.NewMessage()
    msg.Action = "notify"
    msg.Message = "Hello, world!"
    serv.Write(msg)
}

Jekyll Part 2: Archives

« on May 14, 2012 »

Here I'm going to show you how to make an interactive Archives page with categories in Jekyll without using plugins. Very simple and extensible through JavaScript.

What I want to achieve ...

My blog needed an overview page which contains every Blog post, ideally sorted by date. That is fairly easy in pure Jekyll: Just loop over every post and add title and date.

Now here's the catch: I'm using tags to sort my posts into different categories and it would be nice if a user could select a specific tag and get a listing of all blogs with this tag. Fairly basic stuff -- for a dynamic blogging engine. Now, Jekyll supports tags out of the box, but has, at this time, no function to generate a page for each tag. So, everytime we introduce a new tag, we'd need to create a archives page for this tag to loop over the posts. Which, in my opinion, makes Jekyll's tags feature pretty useless.

Plugins would of course solve this problem. But remember my self-imposed constraint mentioned in Part 1? Pure vanilla Jekyll running on GitHub Pages. So, let's try to find another way.

... and how to get there

So, if Jekyll can't generate tag pages out of the box, we'll elevate the problem to the client browser. If our Archives page already contains every post of the blog, we'll just have to hide the ones which do not match our tags. How? With the HTML 5 multi-tool: JavaScript!

We are going to pass the selected category via Hashtag in the URL, for example /archives/#!webdev. JavaScript then extracts the tag and toggles the posts based on whether they match it or not.

Before we dive in, I want to note that you can see the results on my Archives page.

Step 1: The HTML

To make things easier, every post will store its tags in a data- attribute:

{% for post in site.posts %}
<li class="post" data-tags="{{ post.tags | join:',' }}">
    <h1 class="title"><a href="{{ post.url }}">{{ post.title }}</a></h1>
</li>
{% endfor %}

Step 2: JavaScript Voodoo

Jep, I'm using jQuery here. But you should have no problem adapting it to standard JavaScript. The updateTags function extracts the tag from the hash, loops over .post elements, compares their data-tags-attribute against the hash and fades them depending on the result. We also listen for onhashchange to update the selection when a tag link on the same page is clicked.

$(function() {
    function updateTags() {
        var hash = window.location.hash.substr(2);

        $('.post').each(function(i, post) {
            if ($(post).data('tags').indexOf(hash) == -1) {
                $(post).animate({
                    opacity: 0.5,
                    'font-size': '0.8em',
                }, 'fast');
            } else {
                $(post).animate({
                    opacity: 1,
                    'font-size': '1em',
                }, 'fast');
            }
        });
    }

    $(window).bind('hashchange', updateTags)
    updateTags();
})

Bonus: Group Posts by Year

Imagine you want to divide your post listing into different years to achieve something like this:

  • 2012
    • Post 4
    • Post 3
  • 2011
    • Post 2
    • Post 1

It's fairly easy with standard Liquid if you know how. We store the year of the previous post, extract the year of the current one, compare both and output a header if the two differ. That said, here's the code:

{% assign curr_year = "" %}
{% for post in site.posts %}
{% capture post_year %}{{ post.date | date:'%Y' }}{% endcapture %}
{% if post_year != curr_year %}
    <li class="year"><h1>{{ post_year }}</h1></li>
    {% assign curr_year = post_year %}
{% endif %}
    <li class="post">
        <h1 class="title"><a href="{{ post.url }}">{{ post.title }}</a></h1>
    </li>
{% endfor %}

Vim Conceals C++11

« on May 06, 2012 »

Today I found a nice, rather unknown little feature of Vim 7.3: conceal. If enabled, you can replace parts of a line with a shorter symbol, effectively providing in-line folding. This comes in handy for C++11 smart pointers!

I came across this small feature while browsing for new Vim syntax files. The HTML one didn't support the new semantic HTML 5 elements, the CSS one didn't have CSS 3 support, and the default JavaScript indentation was, frankly speaking, the pure horror. So, while I'm browsing around in the Vimiverse, I notice a mailing list entry mentioning the conceal feature. Digging deeper I came across a blog post detailing some possibilities for Ruby. I immediately thought: Hey, this would work for C++, too!

C++11: The Problem

While I absolutely love C++11, because it brings C++ on a level playing field with other modern programming languages by introducing lambda functions, auto, smart pointers and other things, the language becomes even more verbose. The standard recommends using smart pointers for managing object lifetime instead of raw pointers, but that means I need to pass around std::shared_ptr<Renderable> instead of just *Renderable.

To combat the problem, I've used typedef extensively in every class definition to make it a bit more neat:

typedef std::shared_ptr<Renderable> Renderable::Ptr

Problem is, other people won't immediately understand the implementation when seeing Renderable::Ptr for the first time and if I use external libraries, std::shared_ptr will appear for me again.

Vim Conceal

The conceal feature solves both problems. I write normal shared_ptrs and my editor shortens them for me. The result is pretty nice. Here's a comparison.

Some example code without conceal ...

Vim without conceal

... and with conceal enabled.

Vim with conceal

Once you get the idea, long type constructs immediately become much more readable.

Let's talk code

You enable conceal in Vim by setting conceallevel to something other than 0. 1 uses a general character to hide parts, 2 uses a special character depending on the context and 3 just hides it. I should mention that concealing is automatically disabled for the current line so that you can view and edit it. A detailed guide is also available in the Vim Wiki.

I've enabled conceal globally in my .vimrc, together with some different coloring.

" Conceal
set conceallevel=2
hi Conceal ctermbg=234 ctermfg=81

Then I use a custom syntax file addition which I dropped in syntax/cpp.vim:

if !has('conceal')
    finish
endif

syntax match cppSmartPtr "\(std::\)\?unique_ptr" conceal cchar=syntax match cppSmartPtr "\(std::\)\?shared_ptr" conceal cchar=syntax match cppSmartPtr "\(std::\)\?weak_ptr" conceal cchar=

First lines break out from the script if conceal is not supported, the rest matches the different smart pointers and conceals them behind geometric symbols. Should be pretty straight-forward to understand. I have to admit, conceal finally gives me reason to use all those nifty Greek and Unicode characters without the need to care about code compatibility and language support!

I'd like to replace != with and -> with , but lines tend to get visually disturbed rather fast when you select/unselected them.

Jekyll Part 1: Excerpts

« on May 01, 2012 »

Publishing a Jekyll-powered website to GitHub Pages has a serious drawback: no plugin support. This makes it cumbersome to use basic features like archives, tags/categories or excerpts. The first part of this small series deals with how I implemented excerpts while sticking to vanilla Jekyll.

When deciding how to design the overview page for my blog, I was torn between using excerpts or displaying whole blog posts. I chose the first one and soon faced the next problem: How to implement them in Jekyll? Jekyll has no built-in support for excerpts and the Issue is still open.

Method 1: Plugins, but Local

Since Jekyll is static and outputs simple HTML, we could run Jekyll on our local machine and just push the generated code to GitHub. Which in turn means we can use plugins as much as we like. I've seen a lot of people who take this approach by using two branches in their repository. One, source, contains the Jekyll files as you know them and the other, master, holds the output.

Multiple Jekyll plugins are mentioned in the Issue above.

I almost went this way, but I didn't want to manage two different branches and I don't like that small layout changes permeate all generated files which makes commits extremely noisy. So I took it as a challenge to stay as close to pure Jekyll as possible.

Method 2: YAML Front Matter

Enter YAML Front Matter! I could just copy the first few paragraphs into a new variable at the top such as excerpt and then use it in my index page via {{ page.excerpt }}. If you want to use Markdown, just pass it through markdownify: {{ page.excerpt | markdownify }}.

So far, so good. It works fine, but do you really want to duplicate your first few lines everytime you change them? You could automate it, of course -- but either with externals tools or plugins, both not available on GitHub Pages.

Method 3: Liquid Filters to the Rescue!

Update: While this works with latest Jekyll and Liquid, GitHub Pages still hasn't updated their versions and split's behaviour on GitHub is strangely different. So I'm back to Method 2 until there is an update.

What do we need to specify automatically extract excerpts? Some marker where the excerpt should end and the rest of the content begins. Then, some tool to split it at this position and only output the excerpt. Delve deeper into Liquid Filters and you'll soon find some tools to get the job done. The split filter comes into mind, of course.

So, let's do this! First, choose a tag you can embed in your post that serves as the marker and doesn't disturb the normal content. HTML Comments are probably a good candidate. An example:

This is the introduction.

<!-- more -->
And here starts the rest of the page content.

Okay, fine! Now, let's tell Jekyll to split the content at this position. Put this into your post-layout and you're done.

{{ content | split:"<!-- more -->" | first }}

If you want to automate it further and get rid of the comment markers, too, you could simply split by <p> tags and iterate through the first x entries. I'm currently using a variation of this:

{% if excerpt %}
{{ content | split:"</p>" | first }}
<a href="{{ post.url }}">&raquo; Continue reading</a>
{% else %}
{{ content }}
{% endif %}
</p>

Notice the extra </p> at the end which would otherwise be missing since we splitted it.

New Page Goes Live!

« on Apr 22, 2012 »

The new version of my homepage is finally online. No big changes on the overall theme, but rather a complete rewrite of the engine behind. There were a number of reasons I wanted to rebuild it -- mainly responsiveness, more flexibility in migration and to make it future-proof. An overview over the design choices and technology.

The Invisible Gears and Levers

Since I discovered Jekyll, I knew I had to use it somewhere. Jekyll is a site generator and blogging platform with an unusual twist: It generates purely static HTML pages. That means you regenerate your homepage only after you've changed it and then drop it off wherever you want. The webserver does not need PHP, Ruby, SQL or some exotic language, it just serves static files.

And that has a nice advantage: When I want to migrate to another server, I just copy the files and I'm done. I can even host it on Content-Delivery Networks like Google App Engine, Amazon AWS or -- in this case -- GitHub Pages completely free.

GitHub Pages also comes with the added bonus that it actually supports Jekyll. I just push the changes via git-Reposity to GitHub and they run Jekyll automatically for me.

I can also write all my posts in Markdown. You can see all the code for my homepage on Github.

Now With Less CSS and More Metadata

LESS

The rewrite also gave me a chance to use an extended stylesheet language that improves upon CSS. The two major contenders are LESS and Sass. They are both relatively similar in their featureset, at least as far I can see, so I just started with LESS.

Both support the main dealbreakers over CSS -- that is: nesting, variables and mixins. These alone make stylesheets so much easier to write. Only downside is, they both need to be compiled into regular CSS. And since Jekyll does not support this automatically without plugins, this means an extra step when deploying to GitHub.

Grid Systems & Responsiveness

I like grid systems. They keep things nice and organized. No wonder I bookmarked a few on my older journeys through the Internet. There are semantic.gs, Less and its successor Frameless among others. That is also the exact order in which I tried them. I stuck with Frameless until a few moments before production. While I still like the idea of grids, they were of no use to me in this project.

I wanted a simple, responsive website that works on my smartphone and found myself confined in fixed sized blocks with pre-determined gutter width. I tried to fit logo, navigation and footer into these columns, so that they would go along with the content. And then I noticed, my content doesn't even have columns to go along with! Finally, the grid idea found its only use in the three equally sized columns of the footer.

HTML 5

My website is currently written in HTML 5 without any compatibility layers like Modernizr. Since Internet Explorer 6 is finally near extinction, I decided I could try abandoning all backwards-compatibility alltogether. There is no reason not to use the newest browser version.
I tried to include the new semantic tags (like <section> and <article>) as best as possible, as well as to make consistent use of microdata.