title: First GNU Guile Patch and More Guix Packages date: 2013-11-22 21:00 tags: gnu, guix, scheme, guile, wsu summary: I added alist->hash-table procedures for Guile’s native hash table implementation and packaged SDL libraries for Guix. --- I have spent some of the last month working on contributing to GNU Guile and now I can finally say that I have contributed code to the project. Guile has several hash table implementations: a Guile native one, SRFI-69, and R6RS. SRFI-69 contains a handy procedure, `alist->hash-table`, which allows for a sort of hash literal-like syntax: ```scheme (alist->hash-table '((foo . 1) (bar . 2) (baz . 3))) ``` However, I prefer to use Guile’s native hash implementation, and SRFI-69 is incompatible with it, so I decided to port `alist->hash-table`. Unfortunately, it was not as simple as writing just one procedure. The native hash tables actually have 4 different ways of doing key comparisons: Using `equal?`, `eq?`, `eqv?`, and user-defined procedures. This is a design flaw because the user must make sure to use the right procedures at all times rather than simply set the `hash` and `assoc` procedures when creating the hash table instance. Below is the final implementation. Since 3 of the 4 variations were essentially the same, I wrote a short macro to reduce code duplication. ```scheme ;;;; Copyright (C) 2013 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either ;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; Lesser General Public License for more details. ;;;; ;;;; You should have received a copy of the GNU Lesser General Public ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;;; (define-syntax-rule (define-alist-converter name hash-set-proc) (define (name alist) "Convert ALIST into a hash table." (let ((table (make-hash-table))) (for-each (lambda (pair) (hash-set-proc table (car pair) (cdr pair))) (reverse alist)) table))) (define-alist-converter alist->hash-table hash-set!) (define-alist-converter alist->hashq-table hashq-set!) (define-alist-converter alist->hashv-table hashv-set!) (define (alist->hashx-table hash assoc alist) "Convert ALIST into a hash table with custom HASH and ASSOC procedures." (let ((table (make-hash-table))) (for-each (lambda (pair) (hashx-set! hash assoc table (car pair) (cdr pair))) (reverse alist)) table)) ``` Not only did I manage to get my code into Guile, I was given commit access to GNU Guix by the lead developer, Ludovic Courtès. I have never had commit access to any free software project repositories besides my own. I feel quite honored, as cheesy as that may sound. Packages for SDL and SDL2 have been merged into master, and packages for SDL_gfx, SDL_image, SDL_mixer, SDL_net, and SDL_ttf for SDL 1.2 are pending review. I like to show off the elegance of Guix package recipes, so here’s some code: ```scheme ;;; Copyright © 2013 David Thompson ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Guix. If not, see . (define sdl (package (name "sdl") (version "1.2.15") (source (origin (method url-fetch) (uri (string-append "http://libsdl.org/release/SDL-" version ".tar.gz")) (sha256 (base32 "005d993xcac8236fpvd1iawkz4wqjybkpn8dbwaliqz5jfkidlyn")))) (build-system gnu-build-system) (arguments '(#:tests? #f)) ; no check target (inputs `(("libx11" ,libx11) ("libxrandr" ,libxrandr) ("mesa" ,mesa) ("alsa-lib" ,alsa-lib) ("pkg-config" ,pkg-config) ("pulseaudio" ,pulseaudio))) (synopsis "Cross platform game development library") (description "Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware.") (home-page "http://libsdl.org/") (license lgpl2.1))) (define sdl2 (package (inherit sdl) (name "sdl2") (version "2.0.0") (source (origin (method url-fetch) (uri (string-append "http://libsdl.org/release/SDL2-" version ".tar.gz")) (sha256 (base32 "0y3in99brki7vc2mb4c0w39v70mf4h341mblhh8nmq4h7lawhskg")))) (license bsd-3))) ``` Much help is needed to package the GNU system for Guix. If you are interested in helping, please drop by `#guix` on freenode, we are friendly. :)