An Intro to Scheme Macros

In this post I want to go a little deeper into the macro system of Scheme (particularly Chicken), and share a couple of macros I've created.

First of all, macros are what make Scheme and Lisp so exciting. Macros offer the ability to evaluate code at compile time, and modify the structure of a program before it even runs. You can think of it as a really really powerful #define, but where #define lets you modify text, a Lisp macro lets you modify the code structure itself.

There are a couple of different kinds of macro available in Scheme, and as I'm somewhat of a young schemer I'm not completely sure which are available across all implementations and which are only available in Chicken. But I will assume that the macros here can be ported with relative ease.

The first kind, looks a lot like a regular ol' function. It is even called like a function, only when this macro is read it leaves behind whatever it returns. Here's an annotated example:

; Here we are going to create a new macro called "return-me"
; that will simply return in a list whatever is passed to it
(define-syntax return-me
  (syntax-rules () ; Any symbols placed in this list will be ignored
    [(return-me body ...) ; This is what the arguments should look like
     (list body ...)])) ; And this is how they should be transformed

; Example
(return-me "Hello" "World") => ("Hello" "World")
Read more...

A Brief Foray into Haskell

I've tried to learn Haskell in the past and found it completely horrible to look at. That was, until I got around to learning Scheme and decided to look deeper into it.

A couple of nights ago a friend showed me a small piece of Haskell code which reads a series of lines formatted like this:

a 1
b 2
c 3

And sums up the second column. The code looks like this:

foldl1 (+) (map (\c -> read (c !! 1)) (map words (lines "a 1\nb 2\nc 3")))

At first glance, I was at a total loss as to what was going on. So I fumbled around in ghci for a while figuring out what each part was doing.

Read more...

Quake 2 Hacking

http://i.imgur.com/60zIhm.jpg

Quake 2 (aka id Tech 2) is a great game and engine to hack. The source is pretty well laid out and the code is small enough that it doesn't take forever to become familiar with it. It also has a great entity system that makes it a really suitable for prototyping.

I spent the last couple of nights stripping as much of the game code as I could out, right down to the essentials, and then stripping the game data down to the bare minimum as well. I built a plain cube map with a single info_null entity, that gets loaded on startup, acting as a gateway map. The info_null entity contains a "model" key, which loads an arbitrary md2 from disk (in this case, some couch model I found online).

Next I set about embedding Chicken Scheme into the game code as an interpreter, and a few thousand segfaults later, it works! I have output redirection and an "eval" command for the console, allowing you to type some code and get a response.

I also started on a high level API for controlling in game objects that I will just implement as I go, that looks a little like this:

(q2:fire-blaster (q2:get-player-by-name "Player"))

So for just a couple hours of work I have a decent engine and scripting language that can be built up in whatever direction I decide to go with it :D

Comment on this post.

Sawfish Theme, GperfectionHash

http://fc00.deviantart.net/fs70/i/2011/047/a/3/gperfection_hash_for_sawfish_by_hashbox-d39pm73.pngJust a simple modern SawfishWM theme I made, modified from gperfection.

There is a dark version (named perfection-hash), and a light version (named gperfection-hash-light), to suit dark and light GTK themes (not included).

Font in title is "Helvetica Neue Bold 7".

To download, head over to http://hashbox.deviantart.com/art/Gperfection-Hash-for-Sawfish-197710239.

To install, unzip inside ~/.sawfish/themes/ and select gperfection-hash(light) in Sawfish configuration.

Have fun!

Comment on this post.

Chicken Scheme, and FFI

As a follow up on yesterdays post I'm going to show how easy it is to integrate some third party functionality in to a web application to provide "automatic tagging" using libots.

To do this, we're going to use the Chicken FFI. Now this example is really so short that there's no point in splitting it into multiple blocks, so here we go:

;; FFI example
(import foreign)

; Add the libots header
(foreign-declare "#include <libots-1/ots/libots.h>")

; Declare the function we're going to use
(define ots-text-topics
  (foreign-lambda c-string "ots_text_topics" c-string c-string int))

; And here's another useful one
(define ots-summarize
  (foreign-lambda* c-string* ((c-string str) (int percent))
                   "OtsArticle* article = ots_new_article();
                    ots_load_xml_dictionary(article, \"en\");
                    ots_parse_stream(str, strlen(str), article);
                    ots_grade_doc(article);
                    ots_highlight_doc(article, percent);
                    size_t outlen = 0;
                    char *text = ots_get_doc_text(article, &outlen);
                    ots_free_article(article);
                    C_return(text);"))

And now to use it (the automatic tagging part):

;; OTS tagging
(let* ((num-tags 3)
       (body "This is the post you want to tag")
       (tags (ots-text-topics body "en" num-tags)))
  (display (string-append "The tags found are: " tags)))

Now all that's left is to compile it:

csc code.scm `pkg-config --cflags --libs glib-2.0 libots-1 libxml-2.0`

That's really all there is to it!

Comment on this post.

Chicken Scheme, and Web RAD

Recently I've taken more of a liking to Chicken Scheme, and started trying to use it for more of my day to day development. Recently I wrote a port (PongClock ) of a JS + HTML5 Pong Clock into Chicken Scheme using the OpenGL + GLUT libraries. I couldn't believe how smoothly it went, since it was a line by line port, the only thing I needed to write myself were the graphics drawing routines, easy enough since we're only dealing with white rectangles after all, but now it functions as a cross platform screensaver (verified on Linux, OSX, and XP!).

But the area I spend most of my time in is web development, so I was pleased to find the Awful framework for Chicken. Despite the name it is anything but. A simple usage example looks like this:

;; Hello World!
(use awful)

(define-page "/"
  (lambda ()
    "Hello, World!"))

Yes, it really is that easy. Of course you'll most likely want to define your own template, and that is really easy to do too, my templates look something like this:

Read more...

BLACK - Blog Engine

As part of the migration of my blog to the Linode, I've cleaned up and restructured the code that powers this blog somewhat and made it available at BLACK for others to use. Right now it is there more as a reason for me to keep improving it than anything else, since it needs some work.. but hopefully it will become useful enough for someone else to use it in the future.

The "engine" revolves around the single function "post". An example of its usage is below:

<?php black\post($query, function ($post, $issingle) { ?>
  <a href="/<?= $post['id'] ?>/"><?= $post['title'] ?></a>
  <br />
  Posted on <?= date('l, F jS Y', $post['timestamp']) ?>
  <br />
  Tags for this post are <?= $post['tags'] ?>
  <br />
  Aaaannnd the post itself:
  <br />
  <?= $post['body'] ?>
  <br />
  <?php if ($issingle): ?>
     Viewing by post id, so insert Disqus commenting stuff here perhaps?
  <?php endif ?>
<?php }) ?>

Added into an existing website template, the provided function will be called for each post you have, printing them all out to the page.

Comment on this post.

New Server

My blog has been migrated successfully to my Linode, which meant moving from one httpd (Apache) to another (Nginx), transferring MySQL data, and rewriting the rewrites ;)

So far so good. I wasn't expecting it to go smoothly at all. In celebration I've gone through my old posts and deleted or edited stuff that wasn't really relevant or interesting. So hopefully the average post quality has increased a bit :)

Cheers for now! And a belated Merry Christmas and Happy New Year to everyone!

Comment on this post.

My Linode Experience

As mentioned in a previous post, I have been using a Linode for the past few months and I just want to say that the experience I've had has been perfect. I purchased a Linode 512 and I'm using it to host a few small websites on a pretty generic Nginx + PHP5.3 FastCGI stack, along with MySQL and Exim (as a send only MTA), and the whole setup sits comfortably in 50mb of memory and seems to perform well too (time will tell, I haven't done any benchmarks). No special configuration has been needed other than setting up a basic directory layout for my BDSM project, which takes care of pushing my websites from my development box.

/images/Linode_logo.jpeg

I would highly recommended Linode to anyone looking for a VPS, the support is amazingly quick, and the uptime is great; and if you use my referral link to sign up I can get some extra credits, so that would of course be much appreciated :)

Comment on this post.

HashTWM Musings

I know there has been a lot of requests for features to be implemented or fixed in HashTWM. But the reality is, I'm barely using Windows anymore and so I don't have an urgent need for HashTWM.

Despite all the progress around other tiling window managers for Windows I still believe there is room for improvement though, so I am putting some effort into getting a rewrite off the ground. My idea is to get a solid foundation built up that (if anything) through the power of open source, someone will be able to take and hopefully build their dream TWM out of.

Read more...