On Sun, Sep 21, 2025 at 12:47 AM Nikolaos Chatzikonstantinou <[email protected]> wrote: > > Hello bug-guile, > > I have a structure (srfi srfi-9 gnu) that keeps parts of strings in a > binary tree (it's a rope). The intention was to have it immutable, so > I used substring/shared. I kept getting errors on my unit tests when I > referenced individual characters; I could not replicate these errors > on the REPL. Eventually I realized that substring/shared caused them.
I want to offer a small (<100 LoC) reproducible example now. I'm using 3.0.10. Try to run the test suite with autocompilation disabled (--no-auto-compile), and you should get failure (if success, try running again, rarely it succeeds.) If you compile the test.scm file, then it should work fine. I am not sure that I can figure this one out myself further, but somehow it is related to my projects tests being left uncompiled. Does anyone have an insight to the problem here? Regards, Nikolaos Chatzikonstantinou
;; rope, an implementation of string ropes in GNU Guile. ;; Copyright (C) 2025 Nikolaos Chatzikonstantinou ;; ;; This program 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. ;; ;; This program 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 this program. If not, see <https://www.gnu.org/licenses/>. (define-module (data rope) #:export (rope-ref string->random-rope)) (define (rope-length rope) "The length of the rope (also accepts strings)." (if (string? rope) (string-length rope) (+ (rope-length (car rope)) (rope-length (cdr rope))))) (define (rope-ref rope index) "Fetch the character of the rope at the given index." (if (string? rope) (string-ref rope index) (let ((n (rope-length (car rope)))) (if (<= n index) (rope-ref (cdr rope) (- index n)) (rope-ref (car rope) index))))) (define (string->random-rope s) "Generate a random rope representing the given string." (if (string-null? s) "" (let loop ((s s)) (let ((n (random (string-length s)))) (if (zero? n) s (let ((left (loop (substring/shared s 0 n))) (right (loop (substring/shared s n)))) (cons left right))))))) (define (rope left right) "Rope constructor." (cond ((and (string? left) (string-null? left)) right) ((and (string? right) (string-null? right)) left) (else (cons left right))))
;; rope, an implementation of string ropes in GNU Guile. ;; Copyright (C) 2025 Nikolaos Chatzikonstantinou ;; ;; This program 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. ;; ;; This program 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 this program. If not, see <https://www.gnu.org/licenses/>. (use-modules (srfi srfi-64) (data rope)) ;;; Seed the random number generator (set! *random-state* (random-state-from-platform)) (define fuzzying-string "This long string is used for fuzzying purposes to create long random ropes.") (define rope (string->random-rope fuzzying-string)) (test-begin "Rope") (test-eqv "ref with zero index." (string-ref fuzzying-string 0) (rope-ref rope 0)) (test-end "Rope")
