Issue 19

by Mario Domenech Goulart, Moritz Heidkamp and Alaric Snell-Pym

2011-03-24 +0000

0. Introduction

Welcome to issue 19 of the Chicken Gazette.

1. Save The Gazette

As you may have noticed the Gazette hasn't been updated in a while. This is bad as we feel it is a good way to communicate to the outside world what's going on inside Chicken and thus would like to keep it alive. However since it is a volunteer effort it is difficult to keep the regular schedule up. In order to improve this we need your help! If you like Chicken and have some spare time on the weekend, please don't hestitate to contact us through the mailing list or IRC to get involved in authoring the Gazette. Another way to help is by contributing tools for automation of the tedious parts. For more information see Alaric's appeal on the mailing list as well as the Gazette wiki page. Thanks!

2. The Hatching Farm

The following new extensions were added:

The following new versions have been released:

3. Core development

Peter Bex added tail-pattern support to syntax-rules. With that Chicken now fully implements SRFI-46!

Felix Winkelmann added the new top-level command ,m to csi which allows you to set the current module. This means you can for example enter ,m uri-common and you will be inside the uri-common module, i.e. you can also access bindings which aren't exported by it. This can be handy for interactively inspecting and debugging modules.

Jim Ursetto's ticket #486 regarding a problem with the tcp unit got fixed. Also, on the experimental branch, Jim's patch attached to ticket #505 got applied adding the ability to discard input in read-syntax. This makes it possible to implement something like the #; syntax inside Chicken itself. Cool!

There are two other notable changes on the experimental branch: Chicken now links with libpthread on BSD systems to allow linking other libraries that are linked with libpthread themselves. The other patch allows using (const c-string) as a return type of foreign-lambda and as an argument type for define-external.

4. Chicken Talk

Attention all Windows users: Matt Welland has built an all-in-one installer for your platform. This will make it much easier to sneak Chicken into the lair of Microsoft. Thanks a lot Matt!

David Dreisigmeyer announced an update of his Chicken REPL for Python which is an interesting experiment. Any takers for Ruby?

pmarin asked about an offline version of the manual| and it was pointed out that you can either use the manual-labor egg to build a static HTML version of the manual or download it as a PDF from Matt Welland's site.

Another interesting thread was started by Thomas Hintz about using Amazon S3 with Chicken. Apparently it is necessary to calculate HMAC-SHA1 signatures to access it and there is no egg yet to do that. However Thomas said he would create one as well as an S3 egg when he gets around to it.

Patrick Li tried to implement a macroexpand-all function which would expand forms until there are no macros left in it. Unfortunately it turns out that this is not possible for the general case with Chicken at the moment but he ended up with a solution that does as much as is possible.

A longish thread unspun about svnwiki started by Paul Nelson. Unfortunately, svnwiki has not been ported to Chicken 4 so far and since Chicken 3 is deprecated Peter Bex advised him to switch to qwiki instead.

People interested in other programming languages may like Jack Trade's announcement of the Pointless Programming Language Reference. It "features 1,875 solutions to 400 common programming tasks in 7 languages" and Chicken is one of them!

Moritz Heidkamp gave a Lisp workshop with a Chicken focus at the C4 in Cologne, Germany on March 12. A report on it (including the slides used for the presentation) found in the mailing list archive. Another event at the same location took place from March 18 to 20 which was basically a Chicken hacking weekend (as announced on the mailing list). Expect a report on that soon!

Tobia Conforto did an informal benchmark of different programming language implementations printing "Hello, world" to standard out with Chicken scoring quite well. Although it may seem silly at first it makes sense to compare startup overhead of the different implementations which can be relevant for short and simple programs.

Mario Goulart announced that the directory layout for salmonella results and feeds has changed to accommodate reports for multiple branches, OS platforms and hardware architectures. Christian Kellermann has been running salmonella on OpenBSD/x86, using the experimental branch of the chicken-core repository.

On the chicken-hackers mailing list, Jim Ursetto resurrected a thread from 2009 about using the -j option for make to build Chicken in parallel. Jim provided a patch which seems to work fine. See also ticket #526.

Mario Goulart pointed a symlinking issue with libchicken.so which was affecting cross-compiled Chickens. Mario also posted a heads-up regarding to eggs using procedures and type specifier that have been removed from newer versions of Chicken. See tickets #507, #508, #509 and #510.

Still on chicken-hackers and resurrecting topics, Peter Bex re-emerged the distributed egg repository discussion. Peter has written a detailed document covering pros, cons, design goals and description of the system. The mailing list thread is quite long, with several suggestions and considerations from chicken-hackers subscribers.

Chicken has been mentioned on a couple of reddit threads recently: Chicken - Portable, Efficient C Compiler for the Scheme Programming Language (sic) and Using Scheme for practical projects?. The latter has some kind comments from Zane Ashby, who has been blogging about Scheme in general and Chicken (see Chicken Scheme, and FFI and Chicken Scheme, and Web RAD for example).

5. Omelette Recipes

Some time ago I (Alaric) decided I wanted to produce some syntax diagrams for Lojban, a constructed language I'm studying. Syntax diagrams make it really easy to see the possible syntactic structures of things in a language, but are laborious to produce by hand - I wanted to be able to produce them directly from a grammar. So I produced banterpixra (which means "language artist" in Lojban; the "er" is pronounced like in "America" and the "x" is pronounced like a hard h sound, and you'll probably get it right otherwise). A sample of its output can be seen online. But I'm not going to go into much more about banterpixra itself - today, I'm going to talk about the way banterpixra produces nice vector images: generating SVG from Chicken Scheme.

I chose SVG as it's probably the easiest vector format to produce from code, while being widely supported in tools (a growing number of browsers can display it directly, and Inkscape can be used from the command line to convert SVG into raster formats such as PNG, as well as being a full-featured SVG editor and having a standalone SVG viewer).

An SVG file is an XML document describing an image in terms of paths, filled regions, text, and the like. The full list of capabilities of the is quite large, but thankfully, the format is being divided into profiles with optional modules - which means that the SVG Tiny 1.2 specification is thankfully readable while providing most of the tools you could possibly need.

Generating valid XML can be done by pasting strings together, but it's tedious and error-prone - properly handling all the quoting rules is difficult, and if you get it wrong, you produce invalid XML in some cases. Also, if you find yourself wanting to further process the generated XML, you usually have to parse it again in order to expose the structure of it beyond a sequence of characters, which is wasteful. So the preferred technique amongst experienced chicken users is to generate the structure of the XML as s-expressions using the SXML contentions, then use existing tools to convert that to XML as a string.

The top-level structure of an SVG document is a simple template we can wrap around the actual content, given a width and height, like so:

(define (wrap-svg width height content)
  `(svg (@ (xmlns "http://www.w3.org/2000/svg")
	   (version "1.2")
	   (baseProfile "tiny")
	   (viewBox ,(sprintf "0 0 ~S ~S" width height)))
	,@content))

For those not familiar with SXML, what that does is to create a top-level <svg> element with attributes (marked by the @ sublist) setting up an XML namespace, information about the version of SVG in use, and the "viewbox" that defines the bounding box of the image (in our chosen image coordinate system). The content, a list of further elements, is then placed into this element. Rather than specifying 0 0 we could have a nonzero origin, if we wanted to.

The choice of image coordinate system is largely arbitrary - if we are drawing a map, we could use kilometres as our coordinates, even if the entire map then fits into a single kilometre square and all coordinates are fractional. The viewer will scale the image to fit the size of the viewing region, with the viewbox attribute specified. It is also possible to work in the coordinate system of the browser (eg, pixels), and other approaches such as setting up coordinates for physical media such as standard paper sizes - see section 7 of the SVG spec for details.

The content is, largely, a list of objects (such as lines or filled polygons). Perhaps the simplest is a rectangle, defined like so:

(define (make-rect x y w h style)
  `(rect (@ (x ,(number->string x))
	    (y ,(number->string y))
	    ,@style
	    (width ,(number->string w))
	    (height ,(number->string h)))))

style should be a list of styling attributes, such as ((fill "none") (stroke-width "1")) - the full list of styles can be found in section 11 of the specification.

Text is just a matter of specifying coordinates and styling in attributes, then the text goes in the element body:

(define (make-text x y style text)
	`(text (@ (x ,(number->string x))
	       	  (y ,(number->string y))
		  ,@style)
		,text))

Check out section 10 of the specification for details on text styles.

Drawing lines is interesting. SVG contains an embedded sub-language for specifying paths, which can be comprised of straight lines, gaps (eg, the path need not be continuous), and various kinds of curves. This sub-language is specified in section 8 of the specification. Quoting the first example from the specification, M 100 100 L 300 100 L 200 300 z specifies a move to the position (100,100), then a line to the position (300,100), then a line to position (200,300), then the end of the path (that's the z). Those are all absolute coordinates - you can also use coordinates relative to the endpoint of the last operation in the path by using lowercase letters, although the first operation in the path always needs to be an absolute movement (M <x> <y>) to get started.

This string of path data must then be placed into the d attribute of a <path> element, along with styling attributes as per the rectangle object. It's convenient to represent path data as a list of strings and numbers, and then convert it into a <path> element like so:

(define (coords-to-path coords)
  (string-join (map ->string coords) " "))

(define (make-line . coords)
  `(path (@ (d ,(coords-to-path coords))
	    (stroke-width "1")
	    (stroke "black")
	    (fill "none"))))

One can then draw an arrowhead from (bx,by) to (bx+dx,by+dy) with a width of twice w times the length of the arrowhead (eg, set w=0.5 for an arrowhead that's as wide as it is long, and less for a sharper arrow) like so:

(define (make-arrowhead bx by dx dy w)
  (let* ((pdx (* w (- dy)))
	 (pdy (* w dx))
	 (qdx (* w dy))
	 (qdy (* w (- dx)))
	 (px (+ bx pdx))
	 (py (+ by pdy))
	 (qx (+ bx qdx))
	 (qy (+ by qdy))
	 (tx (+ bx dx))
	 (ty (+ by dy)))
  `(path (@ (d ,(coords-to-path
		 (list
		  'M tx ty
		  'L px py
		  'L qx qy
		  'z)))
	    (fill "black")))))

It's also possible to create compound objects, which are themselves just a list of contained objects; this may make the document structure clearer, as many images are made hierarchially by making objects then joining them together. Reflecting this structure in the output SVG makes debugging easier, as you can more easily find your way through the resulting sea of elements, whether you are viewing the XML directly or opening it in an editor such as Inkscape. A group is simply a <g> element surrounding a set of objects, so we can make them with a function like so:

(define (make-group . paths)
  (list (cons 'g (append paths))))

To convert the SXML to XML sent to the current output port, we just need:

(use sxpath-lolevel)
(map display
  (flatten
    (sxml:sxml->xml
      (wrap-svg width height content))))

Given all of the above, it becomes easy to generate pictures.

(define width 100)
(define height 100)
(define content (list
                  (make-rect 5 5 90 90 '((stroke "black") (fill "none")))
                  (make-rect 10 10 80 80 '((stroke "black")))))
(map display
  (flatten
    (sxml:sxml->xml
      (wrap-svg width height content))))

Go, make pretty things!

6. About the Chicken Gazette

The Gazette is produced occasionally by a volunteer from the Chicken community. The latest issue can be found at http://gazette.call-cc.org or you can follow it in your feed reader at http://gazette.call-cc.org/feed.atom. If you'd like to write an issue, consult the wiki for the schedule and instructions!

The chicken image used in the logo is kindly provided and © 2010 by Manfred Wischner