Posts tagged Racket

Mein Wechsel zu Frog

:: Homepage, Racket, Frog

Bisher habe ich mein Blog mit Octopress bereit gestellt. Eine neue Version (“3.0”) ist auf dem Weg. Nachdem in letzter Zeit die einen oder anderen Schwierigkeiten mit meiner Octopress-Installation auftauchten, habe ich mich entschieden, mit dem Blog auf Frog, ebenfalls ein Generator für statische Blogseiten, zu wechseln.

Meine Erfahrungen mit Octopress

  • Ich hatte Octopress und alle Abhängigkeiten in einen Docker-Container gepackt. Das war ganz sinnvoll, um die Ruby-Bibliotheken-Abhängigkeitshölle in den Griff zu bekommen. Es hatte mich aber nur bedingt glücklich gemacht, da ich immer auf Docker angewiesen war, um einen Blogpost zu erzeugen.
  • Einige der Sachen, die Brandon Mathis (dem Autor von Octopress) aufgezeigt hatte, fand ich auch überarbeitungsbedürftig (bspw. das Ausliefern über Git und die enge Verzahnung, die Updates schwierig machte).
  • Was mir sehr gut gefallen hat, war das Layout und Thema sowie auch die Zahl an Plugins und Erweiterungsmöglichkeiten. Da wird mir doch die eine oder andere Möglichkeit fehlen.

Warum nun Frog?

Es gibt ja viele Generatoren für statische Homepages und Blogs. Ich habe mich für den Generator Frog von Greg Hendershott entschieden. Es sprach für mich dafür:

  • Frog ist in Racket geschrieben und da ich das praktisch täglich für allerlei Sachen benutze, liegt es mir deutlich näher als Ruby und ich kann die Abhängigkeiten etc. besser beurteilen und ggf. beheben.
  • Frog verwendet im Standard ein paar HTML-Templates, die dann eine Seite mit Bootstrap-CSS etc. bereit stellen. Da ich eh das eine oder andere mit Bootstrap mache bzw. vorhabe, ist das für mich eine ganz gute Lernmöglichkeit.
  • Die Anpassung von Templates ist für mich einfacher als bei Octopress, da ich dort direkt Racket-Code eingeben und nutzen kann.
  • Wie Octopress/Jekyll verarbeitet Frog Markdown als Eingabeformat. Allerdings kann man auch Scribble-Dateien zum Schreiben von Seiten und Posts verwenden. Scribble verwende ich zwischenzeitlich recht oft als Dokumentations- bzw. Schreibwerkzeug, so dass das ein nettes zusätzliches Feature ist.
  • Es wirkt auf mich, als wäre Frog auch etwas schneller als Octopress im Erzeugen der HTML-Seiten.

Umstellungsaufwand

Frog verarbeitet ebenso wie Octopress Dateien im Markdown-Format; allerdings sind die Metadaten etwas anders formatiert (in Octopress gibt es eine YAML-Präambel). Insofern musste ich alle Blog-Posts (knapp 60 Stück) und Seiten einmal in die Hand nehmen und anpassen. Für die Einrichtung und die Anpassung der Files habe ich ca. eine Stunde gebraucht, dann noch “etwas” Gefummel mit dem CSS und den DNS-Einträgen für die Github Pages. Also durchaus überschaubar.

Zukünftiges

Es gibt beim neuen Blog noch einiges, was ich ergänzen möchte (“Letzte Artikel”-Sidebar, Tag-Sidebar etc.) und mit dem CSS/Thema bin auch noch nicht so zufrieden, aber es tut zumindest nun schon mal.

Ach ja, zum Thema CSS und Fummeln darf natürlich nicht der übliche Hinweis auf diesen (bewegten) Cartoon fehlen.

Using Racket Minimal and raco

:: IT, Lisp, Racket

I use Racket Minimal on my smart phone (this describes how to compile the run time for an ARM based system). It’s is a very small installation of Racket (about 36 MB after installation). After installation one only needs to install the packages that are really neded. But this can be a bit tricky because a lot of packages want to install their documentation and other stuff and bring a whole bunch of files on your drive as dependencies.

Some of the packages are divided up into a "-lib", "-doc" (and sometimes "-test") as laid out in the documentation. With these packages it’s easier to only install the implementation.

A small script of mine used only basic modules and relied on rackunit for the tests. On a mobile device the start up time of such a program can be critical. Therefore it is wise to only require the needed packages and to have the source code being compiled to byte code. One could do this with raco setup (which is included in Minimal Racket) but I wanted to have raco make (which is not part of Minimal Racket) available.

The commands of raco are added via a raco-commands variable in packages’ info.rkt file. I looked through the packages of my “full install” and found the package compiler-lib which adds some commands (make, exe, pack, unpack, decompile, test, expand, read, distribute, demodularize) to raco and relies on only a few other packages. As a result the source and binary files need about 3.8 MB on my phone which is okay for me.

To sum up: After a simple raco pkg install compiler-lib I could easily use raco make and raco test to play with my program on my phone.

How to use GET Bucket location on Amazon S3 with Racket

:: IT, Lisp, Racket, AWS, S3

In Racket I want to iterate over my buckets in Amazon S3. They are located in different regions. So how do I get my bucket’s location/region? In the API Reference there is a call GET Bucket location. I use Greg’s AWS library for Racket and this library authenticates its calls with signature version V4. But V4 requires the user to know the region to correctly sign the request. So I need to know the region to ask Amazon S3 for the region where the bucket is located. Otherwise Amazon S3 responds with an error:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
 <Code>AuthorizationHeaderMalformed</Code>
 <Message>The authorization header is malformed; the region 'us-east-1'
is wrong; expecting 'eu-central-1'</Message>
 <Region>eu-central-1</Region>
 <RequestId>XXXX</RequestId>
 <HostId>XXXX>
</Error>

After some search on the net I found a post on Stackoverflow that helped to solve that issue: If I use the URL format (instead of the normally used virtual host format) I could get the location of any bucket. Every region responds with a LocationConstraint answer.

Therefore a code snippet for Racket could be:

(define (get-bucket-location bucket)
  (parameterize
      ([s3-path-requests? #t])
    (define xpr (get/proc (string-append bucket "/?location") read-entity/xexpr))
    (and (list? xpr)
         (= (length xpr) 3)
         (third xpr))))

For example:

> (get-bucket-location "my-bucket-somewhere")
"eu-central-1"

PS: I think official Amazon S3 documentation could be a bit more verbose on the issues with GetBucketLocation and signature V4.

Update: Greg added a bucket-location function to his great library

How to run Racket on the Raspberry Pi 2

:: IT, Lisp, Racket

I got a Raspberry Pi 2 Model B to play with. I used Raspbian image as operating system. I was wondering how difficult it is to get Racket running on the Raspberry Pi. I downloaded the Unix source + built packages tarball from Racket’s homepage because I only wanted to compile the core of Racket. After unpacking the tarball I was suprised that the instructions were quite short:

From this directory (where the `configure' file is), run the following
commands:

  mkdir build
  cd build
  ../configure
  make
  make install

Between make and make install I had to wait for about 40 minutes but then everything was fine and I could even use DrRacket on the Raspberry Pi:

DrRacket on Raspberry Pi

DrRacket on Raspberry Pi

Very nice and easy to get Racket running on ARM.

PS: Because the Raspberry Pi 2 Model B has an ARMv7 processor the binary runs on my Jolla smart phone as well.

Running Racket on AWS Lambda

:: IT, Lisp, Racket, AWS

I started to use AWS for some projects recently. But I only use few of their services. From time to time I look into some of there services and wonder if they are useful for my tasks. I looked into AWS Lambda, "… a compute service that runs your code in response to events and automatically manages the compute resources for you, making it easy to build applications that respond quickly to new information." Nowadays these “lambda functions” could be written in NodeJS or Java. When I was looking for a roadmap of the supported languages I found an interesting blog post by Ruben Fonseca. He explaind how to run Go code on AWS Lambda.

I tried the same with Racket and wrote a short Racket programm test.rkt:

#lang racket/base

(display (format "Hello from Racket, args: ~a~%" (current-command-line-arguments)))

Then I used raco to create a binary test:

raco exe --orig-exe test.rkt

I took the NodeJS wrapper from Ruben’s blog post and put it in a file main.js:

var child_process = require('child_process');

exports.handler = function(event, context) {
  var proc = child_process.spawn('./test', [ JSON.stringify(event) ], { stdio: 'inherit' });

  proc.on('close', function(code) {
    if(code !== 0) {
      return context.done(new Error("Process exited with non-zero status code"));
    }

    context.done(null);
  });
}

Then I put both files in a zip archive, created a new AWS Lambda function, uploaded the zip file and invoked the function:

Invocation of AWS Lambda function

Invocation of AWS Lambda function

Fine!

PS: Only question is: When is AWS Lambda coming to the region eu-central-1, located in Frankfurt?

Upate (2016–03–15): AWS Lambda is now available in the EU (Frankfurt) region!