Re: Reference implementation attempts to mutate possibly immutable hash table. Marc Nieper-Wißkirchen (11 Jul 2025 18:51 UTC)
(missing)

Re: Reference implementation attempts to mutate possibly immutable hash table. Marc Nieper-Wißkirchen 11 Jul 2025 18:51 UTC

Hi,

Thanks for the bug report. I did the tests on a system that has no
immutable hash tables.

It seems that only one of the versions of `make-hash-table` is
deprecated in SRFI 125.

Have you tried replacing `(hash-table variable-comparator)` by
`(make-hash-table variable-comparator)`?

Marc

Am Fr., 11. Juli 2025 um 19:54 Uhr schrieb Zhu Zihao <xxxxxx@163.com>:
>
> While packaging SRFI-165 for Guix, I found 4 of tests [SRFI-165-test] are failed.
>
> These tests are all try to mutate an immutable hash-table, take 1 as an example:
>
> Test begin:
>   source-file: "/home/citreu/gitrepos/mnieper-show/srfi/165/test.sld"
>   source-line: 91
>   source-form: (test-eqv 42 (let ((x (make-computation-environment-variable (quote x) #f #f)) (env (make-computation-environment))) (computation-environment-update! env x 42) (computation-environment-ref env x)))
> Test end:
>   result-kind: fail
>   actual-value: #f
>   actual-error: (misc-error #f "Hashtable is immutable. ~S" (#hasheq()) #f)
>   expected-value: 42
>
> This is probably caused by attempting to mutate an immutable hash-table
> created by 'hash-table' procedure in SRFI-125 [SRFI-125-spec].
>
> At line 85, the source is
>
> ```
> (define-syntax %define-computation-type
>   (syntax-rules ()
>     ((_ make-environment run () n ((var default e immutable i) ...))
>      (begin
>        (define-values (e ...) (values default ...))
>        (define var (make-environment-variable 'var e immutable i))
>        ...
>        (define (make-environment)
>          (let ((env (make-vector (+ n 2))))
>            (environment-set-global! env (hash-table variable-comparator))
>             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>            (environment-set-local! env (mapping variable-comparator))
>            (vector-set! env (+ i 2) (box e))
> ```
>
> And at line 134, the source is
>
> ```
> (define (computation-environment-update! env var val)
>   (if (predefined? var)
>       (set-box! (environment-cell env var) val)
>       (mapping-ref (environment-local env)
>                    var
>                    (lambda ()
>                      (hash-table-set! (environment-global env) var val))
>                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>                    (lambda (cell)
>                      (set-box! cell val)))))
> ```
>
>
> SRFI-125 specification says:
>
> ```
>  (hash-table comparator [ key value ] ...)
>
> Returns a newly allocated hash table, created as if by make-hash-table using comparator. For each pair of arguments, an association is added to the new hash table with key as its key and value as its value. If the implementation supports immutable hash tables, this procedure returns an immutable hash table. If the same key (in the sense of the equality predicate) is specified more than once, it is an error.
> ```
>
> And the reference implementation of SRFI-125 [SRFI-125-source] does return the
> immutable one, when attempting to mutate it, Guile raise an exception.
>
> I'm not sure how to fix it, SRFI-125 doesn't provides a good way to
> create mutable hash-table (we can only create an immutable one, and copy
> it as mutable). Maybe use `make-hash-table`, but it's a deprecated interface.
>
> [SRFI-165-test]: https://gitlab.com/nieper/show/-/blob/master/srfi/165/test.sld?ref_type=heads
> [SRFI-125-spec]: https://srfi.schemers.org/srfi-125/srfi-125.html
> [SRFI-125-source]: https://github.com/scheme-requests-for-implementation/srfi-125/blob/master/srfi/125.body.scm#L257
>
> Full log attached below:
>
>
> --
> Retrieve my PGP public key:
> 执行下列命令以获取我的 PGP 公有密钥:
>
>   gpg --recv-keys B3EBC086AB0EBC0F45E0B4D433DB374BCEE4D9DC
>
> Zihao