I have assimilated into Vicare the SRFIs 113, 114. Quite some work was needed because, for example, SRFI-114 has no test suite; also, they are written thinking to R7RS implementations and CHICKEN in particular. To assimilate the code to Vicare’s style, I had to touch almost all the procedures definitions.
While doing this work: I have pushed, in parallel, other development tasks.
While working on SRFI-114 assimilation I think I fixed Issue 49. I feel a bit ashamed for taking so long to fix this, because it was a very simple mistake in the compiler; but the cause of error just did not pop up into my mind until now.
It goes like this, when the source optimiser sees code like:
(let ((a 1)) (set! a (do-something)) 2)
it recognises that the binding
a is referenced only in the assignment form, so
to mutate the binding is useless; the code is transformed to the equivalent:
(let ((a 1)) (do-something) 2)
now further optimisations are possible but they do not matter here. Everything is fine with local bindings, but what about top level bindings? If the code is:
(library (demo) (export ;... some bindings ... a) (import (vicare)) ;;... some definitions ... (define a 1) (set! a (do-something)))
a is referenced in the library body only in the assignment form,
but we cannot transform the code to:
(library (demo) (export ;... some bindings ... a) (import (vicare)) ;;... some definitions ... (define a 1) (do-something))
because the binding is exported. Even if the code is:
(library (demo) (export ;... some bindings ... ) (export) (import (vicare)) ;;... some definitions ... (define a 1) (set! a (do-something)))
a is not exported, we cannot transform the code because some
macro might create a non–hygienic reference to the binding.
In general, Vicare’s compiler has no way to detect when a top level binding is referenced in the code or not, so top level bindings can be neither removed nor subject to this kind of source optimisation. But this is exactly what was happening.
When code like the following is expanded:
(library (demo) (export make-record record?) (import (vicare)) (define-record-type record))
a definition for
make-record is created:
(define make-record ...)
then the compiler processes the library body and transforms the top level binding
definitions according to the selected
optimisation policy; the code is transformed to an equivalent of:
(letrec* ((make-record (void)) ...) (set! make-record ...))
letrec* bindings are top level; then the source optimiser is
applied to it. If
make-record is never used in the body other than in the
assignment form: the assignment cannot be removed, but this was happening.
Hence the error.
Some of the “fold left” and “fold right” functions from the library
(vicare containers vectors) have been moved into the boot image, becoming
core primitives; some other primitives were added. In the boot image we now have:
vector-map vector-for-each vector-find vector-for-all vector-exists vector-fold-left vector-fold-right
which constitute a decent base for vector iteration.
Inspired by the functions in SRFI-113 I have added the following core primitives
hashtable-for-each-key hashtable-for-each-entry hashtable-for-all-keys hashtable-for-all-entries hashtable-exists-key hashtable-exists-entry hashtable-find-key hashtable-find-entry hashtable-fold-keys hashtable-fold-entries hashtable->alist alist->hashtable!
and inspired by the functions in SRFI-114 I have extended the suite of hash functions to:
string-hash string-ci-hash symbol-hash bytevector-hash equal-hash fixnum-hash exact-integer-hash flonum-hash number-hash char-hash char-ci-hash boolean-hash void-hash eof-object-hash would-block-hash struct-hash record-hash object-hash
not all of these are quality functions.
For some time, when starting the REPL, the identifier of the last commit was included in the greetings screen:
$ vicare Vicare Scheme version 0.4d0, 64-bit Revision master/84506e3ba00414bd689a87e4890076e4fedd9f56 Build 2015-03-06 Copyright (c) 2006-2010 Abdulaziz Ghuloum and contributors Copyright (c) 2011-2015 Marco Maggi vicare>
now I have removed it:
$ vicare Vicare Scheme version 0.4d0, 64-bit Build 2015-03-11 Copyright (c) 2006-2010 Abdulaziz Ghuloum and contributors Copyright (c) 2011-2015 Marco Maggi and contributors vicare>
To include the “last revision” identifier: after every commit and every branch merge the branch and commit checksum were saved into a file included in the next Vicare build. This meant that after every commit and merge everything needed to be rebuilt, even when no actual code was modified. This annoyed me.
Also, I failed multiple times in keeping in sync the registered revision with the build distributed in tarballs.
For this reasons I nuked this feature. We can live without.