Changelog for husk-scheme-3.14


Made the following enhancements to improve R<sup>7</sup>RS support:

Added a library to compute simple random numbers, based on this Stack Overflow answer:

(import (husk random))
(random num) ; Seed the RNG
(random) ; Random number from 0 to 1
(randint lo hi) ; Generate random integer between lo (optional) and hi



Significant enhancements have been made to the huski REPL:

This release also includes the following features:

Bug fixes:


The major change in this release is support for R<sup>7</sup>RS style library syntax in the compiler. This enables functionality that was previously only available in the interpreter, and sets the stage for husk to begin adding support for R<sup>7</sup>RS.

API changes:

Bug fixes:


This release includes many important fixes and enhancements to the compiler:



This release introduces several performance improvements:

The example game of life program examples/game-of-life/life.scm demonstrates these performance improvements, as it now runs over 4.5 times faster than in the previous release.

This release also adds the following library from R<sup>7</sup>RS:

And, R<sup>5</sup>RS versions of the scheme libraries have been relocated to underneath (scheme r5rs). Each of these libraries exposes a husk subset of the functions recommended by R<sup>7</sup>RS:

Changes to the Haskell API:

Bug fixes:


A major change for this release is the introduction of Scheme libraries using R<sup>7</sup>RS library syntax. For an example of how to use libraries, see examples/hello-library/hello.scm in the husk source tree. Note that since R<sup>7</sup>RS is not currently implemented by husk, the library system only has the built-in import (r5rs base) to allow you to import the standard husk R5RS environment. Also, please keep in mind this is still a beta feature that is not yet implemented by the compiler.

This release also contains many improvements to the Haskell API:

Bug fixes:


Added support for R<sup>7</sup>RS bytevectors.

Improved support for using husk as an extension language by adding Haskell function evalLisp'. This function evaluates a lisp data structure and returns the LispVal or LispError result directly:

evalLisp' :: Env -> LispVal -> IO (ThrowsError LispVal)

This makes it much easier to retrieve results when using husk as an extension language:

result <- evalLisp' env $ List [Atom "/", Number 1, Number 0]
case result of
  Left err -> putStrLn $ "Error: " ++ (show err)
  Right val -> putStrLn $ show val

Finally, fixed a bug where setting a variable to refer back to itself would result in an infinite loop. For example, the last line of the following code would cause huski to hang:

(define a '())
(define b a)
(define a b)


This release adds support for nested quasi-quotation forms, which now respect depth level. This was done by replacing the quasi-quotation special form with a macro based on the one from chibi scheme. A nice side-benefit is that by removing the special forms, quasi-quotation now works in the compiler.

Also added support for SRFI 2, and-let*. From the SRFI document:

Like an ordinary AND, an AND-LET* special form evaluates its arguments - expressions - one after another in order, until the first one that yields #f. Unlike AND, however, a non-#f result of one expression can be bound to a fresh variable and used in the subsequent expressions. AND-LET* is a cross-breed between LET* and AND.

And added support for environment specifiers, including the following functions:

This release also includes the following bug fixes:


Added support for GHC 7.6.


Enhanced the variable storage model to correctly store references to objects. For example, consider the following:

(define x (list 'a 'b 'c))
(define y x)
(set-cdr! x 4)

After executing this code, previous versions of husk assigned (a b c) to y. With this release, husk now evaluates y to the expected value of (a . 4).

The more general problem is that certain data types denote a memory location which may be modified by mutator functions such as set-cdr!. This is discussed specifically in section 3.4 <b>Storage Model</b>:

Variables and objects such as pairs, vectors, and strings implicitly denote locations or sequences of locations. A string, for example, denotes as many locations as there are characters in the string. (These locations need not correspond to a full machine word.) A new value may be stored into one of these locations using the string-set! procedure, but the string continues to denote the same locations as before.

Internally husk uses Haskell data types, so the husk model differs slightly from the one in R<sup>5</sup>RS - references are used instead of individual memory locations. This has implications for the set-car! and set-cdr! special forms, where circular lists and similar low-level optimizations are not possible as Haskell lists are used instead of raw pointers. However, these issues aside, the enhanced storage model is a big step forward to bringing husk's variable support closer in line to that of other Schemes.


The major change in this release is support for explicit renaming macros. This low-level macro system provides the ability to break macro hygiene, if necessary, and offers a macro system that is similar to defmacro.

In addition, all of the character functions from R<sup>5</sup>RS have been implemented.







This release adds full support for GHC 7.2.2 / 7.4.1 as well as a number of small enhancements.


This is a series of quick bug-fix releases that allows husk to build under GHC 7.4.1.




This release continues the trend of quick point releases for the 3.4.x series. The key change is support for GHC 7.2:




Added experimental support for let-syntax and letrec-syntax.

Bug fixes:


This release adds the first hygienic macro support to husk. There are two "sides" to macro hygiene:

Support has been added for both sides, although there are some issues as noted in the Version 3.4.x Milestones. Macro support will continue to improve in future releases.

In addition, this release contains the following bug fixes:


This release includes major improvements to the macro module. In particular:

Other changes:




(let ((if +)) (if 1 2 3)) was 2 instead of 6. Now it eval's to 6