Planet Scheme

January 19, 2018

Programming Praxis

Roomba

A robot can move any number of steps in the four cardinal directions. Given the robot’s initial position and a string of moves given as, for instance, N3E5S2W6 (any of the four cardinal directions, followed by any number of steps, as many commands as desired), determine the ending position of the robot.

Your task is to write a program to determine the ending position of a robot, given a starting position and a string of move commands. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at January 19, 2018 10:00 AM

January 17, 2018

Andy Wingo

instruction explosion in guile

Greetings, fellow Schemers and compiler nerds: I bring fresh nargery!

instruction explosion

A couple years ago I made a list of compiler tasks for Guile. Most of these are still open, but I've been chipping away at the one labeled "instruction explosion":

Now we get more to the compiler side of things. Currently in Guile's VM there are instructions like vector-ref. This is a little silly: there are also instructions to branch on the type of an object (br-if-tc7 in this case), to get the vector's length, and to do a branching integer comparison. Really we should replace vector-ref with a combination of these test-and-branches, with real control flow in the function, and then the actual ref should use some more primitive unchecked memory reference instruction. Optimization could end up hoisting everything but the primitive unchecked memory reference, while preserving safety, which would be a win. But probably in most cases optimization wouldn't manage to do this, which would be a lose overall because you have more instruction dispatch.

Well, this transformation is something we need for native compilation anyway. I would accept a patch to do this kind of transformation on the master branch, after version 2.2.0 has forked. In theory this would remove most all high level instructions from the VM, making the bytecode closer to a virtual CPU, and likewise making it easier for the compiler to emit native code as it's working at a lower level.

Now that I'm getting close to finished I wanted to share some thoughts. Previous progress reports on the mailing list.

a simple loop

As an example, consider this loop that sums the 32-bit floats in a bytevector. I've annotated the code with lines and columns so that you can correspond different pieces to the assembly.

   0       8   12     19
 +-v-------v---v------v-
 |
1| (use-modules (rnrs bytevectors))
2| (define (f32v-sum bv)
3|   (let lp ((n 0) (sum 0.0))
4|     (if (< n (bytevector-length bv))
5|         (lp (+ n 4)
6|             (+ sum (bytevector-ieee-single-native-ref bv n)))
7|          sum)))

The assembly for the loop before instruction explosion went like this:

L1:
  17    (handle-interrupts)     at (unknown file):5:12
  18    (uadd/immediate 0 1 4)
  19    (bv-f32-ref 1 3 1)      at (unknown file):6:19
  20    (fadd 2 2 1)            at (unknown file):6:12
  21    (s64<? 0 4)             at (unknown file):4:8
  22    (jnl 8)                ;; -> L4
  23    (mov 1 0)               at (unknown file):5:8
  24    (j -7)                 ;; -> L1

So, already Guile's compiler has hoisted the (bytevector-length bv) and unboxed the loop index n and accumulator sum. This work aims to simplify further by exploding bv-f32-ref.

exploding the loop

In practice, instruction explosion happens in CPS conversion, as we are converting the Scheme-like Tree-IL language down to the CPS soup language. When we see a Tree-Il primcall (a call to a known primitive), instead of lowering it to a corresponding CPS primcall, we inline a whole blob of code.

In the concrete case of bv-f32-ref, we'd inline it with something like the following:

(unless (and (heap-object? bv)
             (eq? (heap-type-tag bv) %bytevector-tag))
  (error "not a bytevector" bv))
(define len (word-ref bv 1))
(define ptr (word-ref bv 2))
(unless (and (<= 4 len)
             (<= idx (- len 4)))
  (error "out of range" idx))
(f32-ref ptr len)

As you can see, there are four branches hidden in the bv-f32-ref: two to check that the object is a bytevector, and two to check that the index is within range. In this explanation we assume that the offset idx is already unboxed, but actually unboxing the index ends up being part of this work as well.

One of the goals of instruction explosion was that by breaking the operation into a number of smaller, more orthogonal parts, native code generation would be easier, because the compiler would only have to know about those small bits. However without an optimizing compiler, it would be better to reify a call out to a specialized bv-f32-ref runtime routine instead of inlining all of this code -- probably whatever language you write your runtime routine in (C, rust, whatever) will do a better job optimizing than your compiler will.

But with an optimizing compiler, there is the possibility of removing possibly everything but the f32-ref. Guile doesn't quite get there, but almost; here's the post-explosion optimized assembly of the inner loop of f32v-sum:

L1:
  27    (handle-interrupts)
  28    (tag-fixnum 1 2)
  29    (s64<? 2 4)             at (unknown file):4:8
  30    (jnl 15)               ;; -> L5
  31    (uadd/immediate 0 2 4)  at (unknown file):5:12
  32    (u64<? 2 7)             at (unknown file):6:19
  33    (jnl 5)                ;; -> L2
  34    (f32-ref 2 5 2)
  35    (fadd 3 3 2)            at (unknown file):6:12
  36    (mov 2 0)               at (unknown file):5:8
  37    (j -10)                ;; -> L1

good things

The first thing to note is that unlike the "before" code, there's no instruction in this loop that can throw an exception. Neat.

Next, note that there's no type check on the bytevector; the peeled iteration preceding the loop already proved that the bytevector is a bytevector.

And indeed there's no reference to the bytevector at all in the loop! The value being dereferenced in (f32-ref 2 5 2) is a raw pointer. (Read this instruction as, "sp[2] = *(float*)((byte*)sp[5] + (uptrdiff_t)sp[2])".) The compiler does something interesting; the f32-ref CPS primcall actually takes three arguments: the garbage-collected object protecting the pointer, the pointer itself, and the offset. The object itself doesn't appear in the residual code, but including it in the f32-ref primcall's inputs keeps it alive as long as the f32-ref itself is alive.

bad things

Then there are the limitations. Firstly, instruction 28 tags the u64 loop index as a fixnum, but never uses the result. Why is this here? Sadly it's because the value is used in the bailout at L2. Recall this pseudocode:

(unless (and (<= 4 len)
             (<= idx (- len 4)))
  (error "out of range" idx))

Here the error ends up lowering to a throw CPS term that the compiler recognizes as a bailout and renders out-of-line; cool. But it uses idx as an argument, as a tagged SCM value. The compiler untags the loop index, but has to keep a tagged version around for the error cases.

The right fix is probably some kind of allocation sinking pass that sinks the tag-fixnum to the bailouts. Oh well.

Additionally, there are two tests in the loop. Are both necessary? Turns out, yes :( Imagine you have a bytevector of length 1025. The loop continues until the last ref at offset 1024, which is within bounds of the bytevector but there's one one byte available at that point, so we need to throw an exception at this point. The compiler did as good a job as we could expect it to do.

is is worth it? where to now?

On the one hand, instruction explosion is a step sideways. The code is more optimal, but it's more instructions. Because Guile currently has a bytecode VM, that means more total interpreter overhead. Testing on a 40-megabyte bytevector of 32-bit floats, the exploded f32v-sum completes in 115 milliseconds compared to around 97 for the earlier version.

On the other hand, it is very easy to imagine how to compile these instructions to native code, either ahead-of-time or via a simple template JIT. You practically just have to look up the instructions in the corresponding ISA reference, is all. The result should perform quite well.

I will probably take a whack at a simple template JIT first that does no register allocation, then ahead-of-time compilation with register allocation. Getting the AOT-compiled artifacts to dynamically link with runtime routines is a sufficient pain in my mind that I will put it off a bit until later. I also need to figure out a good strategy for truly polymorphic operations like general integer addition; probably involving inline caches.

So that's where we're at :) Thanks for reading, and happy hacking in Guile in 2018!

by Andy Wingo at January 17, 2018 10:30 AM

January 16, 2018

Programming Praxis

Square-Sum Puzzle

I don’t watch a lot of television, but the YouTube channel Numberphile is one of the places I am careful not to miss. Numberphile recently had an episode called “The Square-Sum Puzzle” that makes a good exercise:

Rearrange the numbers from 1 to 15 so that any two adjacent numbers must sum to a square number.

Your task is to write a program to solve the Numberphile square-sum puzzle. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at January 16, 2018 10:00 AM

January 12, 2018

Programming Praxis

Binary Gap

A binary gap is a sequence of 0-bits between 1-bits in the binary representation of a number. For instance, 2010 = 101002 has a binary gap of length 1 between its first and third bits; the two 0-bits that end the number are not part of a binary gap because there is no trailing 1-bit. Thus, the length of the maximal binary gap in 20 is 1. The length of the maximal binary gap in 52910 = 10000100012 is 4.

Your task is to write a program that finds the length of the maximal binary gap in a number. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at January 12, 2018 10:00 AM

January 09, 2018

Programming Praxis

Three In A Row

In today’s exercise we are given a file and asked to find the userid’s of customers that appeared on three successive days. The input file contains a date in MM/DD/YYYY format, a tab character, and a userid (a four-digit integer):

01/11/2018\t0003
01/12/2018\t0003
01/13/2018\t0004
01/13/2018\t0003

 

In this case, customer 3 appeared on three successive days, 1/11, 1/12 and 1/13. You may assume the input is properly formed.

Your task is to write a program that finds customers who appeared on three successive days. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at January 09, 2018 10:00 AM

January 05, 2018

Programming Praxis

Sorting By Frequency

We have another homework question today, as I continue clearing out my backlog of people who sent me email asking for homework help last fall:

You are given an array with duplicates, and are to sort the array by decreasing frequency of elements. If two elements have the frequency, sort them in increasing order of value. For instance, the input (2 3 5 3 7 9 5 3 7) is sorted as (3 3 3 5 5 7 7 2 9).

Your task is to write a program that sorts by frequency. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at January 05, 2018 10:00 AM

January 02, 2018

Programming Praxis

Two List Tasks

We have today two simple exercises on lists:

  1. Given a list of lists of integers, all the same length, return a list of the sums of the lists. For instance, given the list ((1 2 3 4) (2 3 4 5) (3 4 5 6)), return the list ((+ 1 2 3) (+ 2 3 4) (+ 3 4 5) (+ 4 5 6)), which is (6 9 12 15).
  2. Given a list of integers of length n = k × m, return a list of k items, each containing the sum of the next m integers from the original list. For instance, given the list, (1 2 3 4 2 3 4 5 3 4 5 6) and sub-list length m = 4, return the list (10 14 18).

Your task is to write programs that perform the two tasks. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at January 02, 2018 10:00 AM

December 22, 2017

GNU Guix

Porting GuixSD to ARMv7

GuixSD porting to ARMv7 is a difficult topic. There are plenty of different machines, with specific hardware configurations and vendor-tuned bootloaders, and ACPI support is still experimental. For those reasons it is currently impossible to provide a GuixSD image that runs on most ARMv7 machines like on x86_64 targets.

The GuixSD port on ARMv7 has to be done machine by machine and the first supported one is the BeagleBone Black. It was choosen mainly because it runs with mainline U-Boot and Linux-libre kernel.

As Guix already supported armv7, only three things were missing:

  1. A rework of the GuixSD bootloader layer to support not just GRUB but also U-Boot and Extlinux. This has been integrated in the 0.14 release.
  2. Some developments and fixes on Guix scripts to support image generation, system reconfiguration and installation on ARMv7 in the same way as it is already possible on i686 and x86_64 machines.
  3. The definition on an installation image for the BeagleBone Black.

Points 2 and 3 were addressed recently so we are now ready to show you how to run GuixSD on your BeagleBone Black board!

Installing GuixSD on a BeagleBone Black

Let&aposs try to install GuixSD on the 4GB eMMC (built-in flash memory) of a BeagleBone Black.

Future Guix releases will provide pre-built installer images for the BeagleBone Black. For now, as support just landed on "master", we need to build this image by ourselves.

This can be done this way:

guix system disk-image --system=armhf-linux -e "(@ (gnu system install) beaglebone-black-installation-os)"

Note that it is not yet possible to cross-compile a disk image. So you will have to either run this command on an armhf-linux system where you have previously installed Guix manually, or offload the build to such a system.

You will eventually get something like:

installing bootloader...
[ 7710.782381] reboot: Restarting system
/gnu/store/v33ccp7232gj5wdahdgpjcw4nvh14d7s-disk-image

Congrats! Let&aposs flash this image onto a microSD card with the command:

dd if=/gnu/store/v33ccp7232gj5wdahdgpjcw4nvh14d7s-disk-image of=/dev/mmcblkX bs=4M

where mmcblkX is the name of your microSD card on your GNU/Linux machine.

You can now insert the microSD card into you BeagleBone Black, plug in a UART cable and power-on your device while pressing the "S2" button to force the boot from microSD instead of eMMC.

GuixSD installer on BeagleBone Black

Let&aposs follow the Guix documentation here to install GuixSD on eMMC.

First of all, let&aposs plug in an ethernet cable and set up SSH access in order to be able to get rid of the UART cable.

ifconfig eth0 up
dhclient eth0
herd start ssh-daemon

Let&aposs partition the eMMC (/dev/mmcblk1) as a 4GB ext4 partition, mount it, and launch the cow-store service, still following the documentation.

cfdisk
mkfs.ext4 -L my-root /dev/mmcblk1p1
mount LABEL=my-root /mnt
herd start cow-store /mnt

We have reached the most important part of this whole process. It is now time to write the configuration file of our new system. The best thing to do here is to start from the template beaglebone-black.scm:

mkdir /mnt/etc
cp /etc/configuration/beaglebone-black.scm /mnt/etc/config.scm
zile /mnt/etc/config.scm

Once you are done preparing the configuration file, the new system must be initialized with this command:

guix system init /mnt/etc/config.scm /mnt

When this is over, you can turn off the board and remove the microSD card. When you&aposll power it on again, it will boot a bleeding edge GuixSD---isn&apost that nice?

Preparing a dedicated system configuration

Installing GuixSD on eMMC is great but you can also use Guix to prepare a portable microSD card image for your favorite server configuration. Say you want to run an mpd server on a BeagleBone Black directly from microSD card, with a minimum of configuration steps.

The system configuration could look like this:

(use-modules (gnu) (gnu bootloader extlinux))
(use-service-modules audio networking ssh)
(use-package-modules screen ssh)

(operating-system
  (host-name "my-mpd-server")
  (timezone "Europe/Berlin")
  (locale "en_US.utf8")
  (bootloader (bootloader-configuration
               (bootloader u-boot-beaglebone-black-bootloader)
               (target "/dev/sda")))
  (initrd (lambda (fs . rest)
            (apply base-initrd fs
                   ;; This module is required to mount the sd card.
                   #:extra-modules (list "omap_hsmmc")
                   rest)))
  (file-systems (cons (file-system
                        (device "my-root")
                        (title &aposlabel)
                        (mount-point "/")
                        (type "ext4"))
                      %base-file-systems))
  (users (cons (user-account
                (name "mpd")
                (group "users")
                (home-directory "/home/mpd"))
               %base-user-accounts))
  (services (cons* (dhcp-client-service)
                   (service mpd-service-type)
                   (agetty-service
                    (agetty-configuration
                     (extra-options &apos("-L"))
                     (baud-rate "115200")
                     (term "vt100")
                     (tty "ttyO0")))
                   %base-services)))

After writing this configuration to a file called mpd.conf, it&aposs possible to forge a disk image from it, with the following command:

guix system disk-image --system=armhf-linux mpd.conf

Like in the previous section, the resulting image should be copied to a microSD card. Then, booting from it on the BeagleBone Black, you should get:

...
Service mpd has been started.
This is the GNU system.  Welcome.
my-mpd-server login:

With only two commands you can build a system image from a configuration file, flash it and run it on a BeagleBone Black!

Next steps

  • Porting GuixSD to other ARMv7 machines.

While most of the work for supporting ARMv7 machines is done, there&aposs still work left to create specific installers for other machines. This mostly consists of specifying the right bootloader and initrd options, and testing the whole thing.

One of the next supported systems might be the EOMA68-A20 as we should get a pre-production unit soon. Feel free to add support for your favorite machine!

This topic will be discussed in a future post.

  • Allow system cross-compilation.

This will be an interesting feature to allow producing a disk image from a desktop machine on x86_64 for instance. More development work is needed, but we&aposll keep you informed.

About GNU Guix

GNU Guix is a transactional package manager for the GNU system. The Guix System Distribution or GuixSD is an advanced distribution of the GNU system that relies on GNU Guix and respects the user&aposs freedom.

In addition to standard package management features, Guix supports transactional upgrades and roll-backs, unprivileged package management, per-user profiles, and garbage collection. Guix uses low-level mechanisms from the Nix package manager, except that packages are defined as native Guile modules, using extensions to the Scheme language. GuixSD offers a declarative approach to operating system configuration management, and is highly customizable and hackable.

GuixSD can be used on an i686, x86_64 and armv7 machines. It is also possible to use Guix on top of an already installed GNU/Linux system, including on mips64el and aarch64.

by Mathieu Othacehe at December 22, 2017 01:00 PM

December 20, 2017

Ben Simon

Helping bash and tinyscheme get along | Friendlier command line execution of scheme code

I was looking for a cleaner way to manage SDR Touch radio frequencies and I thought I'd give Scheme S-expressions a go.

I quickly arrived at this 'format':

(("Arl,VA"
  (166.9 "DC Police?")
  (166.7 "Dc Police?"))

 ("OnABoat"
  (462 "FRS Low")
  (467 "FRS High")
  (457.5 "Marine1")
  (467.5 "Marine2")
  (467.7 "Marine3"))

 ("NCL"
  (457.5250 "Bridge Ops")
  (457.5500 "Engineering")
  (457.5750 "???"))

Because I programmed the solution in Scheme, turning this basic set of S-expressions into the required mess of XML was straightforward. You can find the solution here. I have to say, it was a real delight using S-Expressions to solve this one. XML, JSON and raw text all jumped out at me as options, but in this case, S-Expressions were the clear way to go.

I coded this solution on my Android device using Termux, emacs and Tinyscheme.

While the solution worked great under emacs' interactive scheme mode, I decided I wanted the ability to run the conversion command from a bash prompt. While tinyscheme has some basic command line handling, it was lacking a few details, such as the ability to get the script's working directory. This may seem like an obscure requirement, but with this value I'm able to reliably (load ...) files without worrying about running the script from a specific directory.

To make tinyscheme more command line friendly, I created tsexec, a small script below that kicks off tinyscheme with a number of helpful functions predefined. These include:

(cmd-arg0) - returns the name of scheme script that is currently executing.

(cmd-args) - returns the list of command line arguments passed to the currently executing script.

(cmd-dir . path) - when invoked with no arguments, returns the directory the currently executing script lives in. When an argument is provided, the value is prefixed with the source script's directory.

Using these functions I'm was able to write a command line friendly version of my scheme code to generate XML.

(load (cmd-dir "utils.scm"))  ;; utils.scm is now imported in a location independent way

(define (make-presets frequency-file xml-file)
  (with-output-to-file xml-file
    (lambda ()
      (with-data-from-file frequency-file
       (lambda (data)
  (show "<?xml version='1.0' encoding='UTF-8'?>")
  (show "<sdr_presets version='1'>")
  (for-each (lambda (category)
       (show "<category id='" (gen-id) "' name='" (car category) "'>")
       (for-each (lambda (preset)
     (show "<preset id='" (gen-id) "' ")
     (show "        name='" (cadr preset) "' ")
     (show "        freq='" (freqval (car preset)) "' ")
     (show "        centfreq='" (freqval (car preset)) "' ")
     (show "        offset='0'")
     (show "        order='" (gen-id) "' ")
     (show "        filter='10508' ")
     (show "        dem='1' ")
     (show "/>"))
          (cdr category))
       (show "</category>"))
     data)
  (show "</sdr_presets>"))))))
  

;; Simple argument handling below
(cond
 ((= 1 (length (cmd-args)))
  (make-presets (car (cmd-args)) "SDRTouchPresets.xml"))
 ((= 2 (length (cmd-args)))
  (make-presets (car (cmd-args)) (cadr (cmd-args))))
 (else
  (show "Need to provide frequency and output file to continue.")))

Here's a few screenshots of me running this code:

Termux has a handy add-on that allows you to invoke shell scripts from your phone's home screen. I'm thinking tsexec may be an ideal way to connect up this short-cut ability to tinyscheme.

Finally, here's the source code for tsexec. Enjoy!

#!/data/data/com.termux/files/usr/bin/bash

##
## Execute a tinyscheme script. Setup various functions that can
## be used to access command line args and such
##

if [ ! -f "$1" ] ; then
    echo "Refusing to run non-existant script [$1]"
    exit 1
fi

CMD_DIR=$(pwd)/$(dirname $1)
CMD_ARG0=$(basename $1)
CMD_MAIN="$CMD_DIR/$CMD_ARG0"
shift

CMD_ARGS=""
for arg in "$@" ; do
  CMD_ARGS="$CMD_ARGS \"$arg\""
done


if [ ! -f "$CMD_MAIN" ] ; then
    echo "Failed to derive CMD_DIR, guessed: $CMD_DIR"
    exit 2
fi

wrapper() {
  cat <<EOF
;; Autogenerated scheme wrapper script
(define (cmd-arg0) 
  "$CMD_ARG0")

(define (cmd-dir . path)
  (if (null? path)
      "$CMD_DIR"
      (string-append "$CMD_DIR/" (car path))))

(define (cmd-args)
  (list $CMD_ARGS))

(load "$CMD_MAIN")
EOF
}

wrapper > $HOME/.ts.$$
tinyscheme $HOME/.ts.$$
rm $HOME/.ts.$$

by Ben Simon (noreply@blogger.com) at December 20, 2017 08:44 PM

December 19, 2017

Programming Praxis

Merry Christmas!

I’ll be taking a break until the new year, as my daughter is visiting from out-of-town and daily hits are cut about in half at the end of the academic year. I wish a Merry Christmas and Happy New Year to my readers and their families.

sveta-gora-nativity1

by programmingpraxis at December 19, 2017 10:00 AM

December 15, 2017

Programming Praxis

Rotated Palindrome

Today’s exercise provides simple finger exercise for a Friday morning:

A palindrome is a string that reads the same forward and backward; for instance “abcdedcba” is a palindrome. A rotated palindrome is a string that reads the same forward and backward, either directly or in any rotation of the string; for instance, “dedcbaabc” is a rotated palindrome, because if the last three letters at the end of the string are rotated to the beginning of the string, it becomes “abcdedcba” which is a palindrome.

Your task is to write a program to determine if a string is a rotated palindrome. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at December 15, 2017 10:00 AM

December 12, 2017

Programming Praxis

Jane’s Homework

Today’s exercise is from user Jane, who needs homework help:

Consider all partitionings of a list of positive integers into two partitions. For each partitioning, compute the sums of the two partitions, then compute the least common multiple of the two sums. Report the maximum of all possible least common multiples. For example, given the list (2 3 4 6), the possible partitionings, the associated sums, and the least common multiples, are:

    () (2 3 4 6) -  0 15 -  0
    (2)  (3 4 6) -  2 13 - 26
    (3)  (2 4 6) -  3 12 - 12
    (2 3)  (4 6) -  5 10 - 10
    (4)  (2 3 6) -  4 11 - 44
    (2 4)  (3 6) -  6  9 - 18
    (3 4)  (2 6) -  7  8 - 56
    (2 3 4)  (6) -  9  6 - 18
    (6)  (2 3 4) -  6  9 - 18
    (2 6)  (3 4) -  8  7 - 56
    (3 6)  (2 4) -  9  6 - 18
    (2 3 6)  (4) - 11  4 - 44
    (4 6)  (2 3) - 10  5 - 10
    (2 4 6)  (3) - 12  3 - 12
    (3 4 6)  (2) - 13  2 - 26
    (2 3 4 6) () - 15  0 -  0

Thus, the maximum least common multiple is 56.

Jane writes that she wants to be able to recursively find all partitions given a list, and she thinks she will have to use lambda in her program.

Your task is to write a program that finds the maximum least common multiple of the part-sums of all possible 2-partitionings of a list of positive integers. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at December 12, 2017 10:00 AM

December 08, 2017

Programming Praxis

Deletion From A Cyclical List

A cyclical list has no beginning and no end; Chez Scheme writes it like this:

#0=(1 2 3 . #0#)

Your task is to write a program that removes an item from a cyclical list; if the item is not present in the cyclical list, it should remain unchanged. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at December 08, 2017 10:00 AM

December 07, 2017

GNU Guix

GNU Guix and GuixSD 0.14.0 released

We are pleased to announce the new release of GNU Guix and GuixSD, version 0.14.0!

The release comes with GuixSD ISO-9660 installation images, a virtual machine image of GuixSD, and with tarballs to install the package manager on top of your GNU/Linux distro, either from source or from binaries.

It’s been 6 months since the previous release, during which 88 people contributed code and packages. The highlights include:

See the release announcement for details.

About GNU Guix

GNU Guix is a transactional package manager for the GNU system. The Guix System Distribution or GuixSD is an advanced distribution of the GNU system that relies on GNU Guix and respects the user&aposs freedom.

In addition to standard package management features, Guix supports transactional upgrades and roll-backs, unprivileged package management, per-user profiles, and garbage collection. Guix uses low-level mechanisms from the Nix package manager, except that packages are defined as native Guile modules, using extensions to the Scheme language. GuixSD offers a declarative approach to operating system configuration management, and is highly customizable and hackable.

GuixSD can be used on an i686 or x86_64 machine. It is also possible to use Guix on top of an already installed GNU/Linux system, including on mips64el, armv7, and aarch64.

by Ludovic Courtès at December 07, 2017 01:00 PM

December 05, 2017

Programming Praxis

Recursion And Iteration

Today’s exercise is about basic programming techniques.

Your task is to pick a function and write two versions of it, one recursive, the other iterative; compare the two versions on readability, programming ease, speed, and any other criteria that are important to you. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at December 05, 2017 02:00 PM