diff --git a/uniseg/graphemes/stream.scm b/uniseg/graphemes/stream.scm index 882c32d..0a6fd29 100644 --- a/uniseg/graphemes/stream.scm +++ b/uniseg/graphemes/stream.scm @@ -15,14 +15,19 @@ ;; TODO: the golang uniseg also does word and sentence boundaries. These state machines could be implemented if we wanted to. (define-immutable-record-type - (make-grapheme glyphs width) + (make-grapheme width glyphs-promise string-promise) grapheme? - (glyphs grapheme-glyphs) - (width grapheme-width)) + (width grapheme-width) + (glyphs-promise _grapheme-glyphs-promise) + (string-promise _grapheme-string-promise)) + +(define (grapheme-glyphs grapheme) + "Return a lazily-constructed list of glyphs in the grapheme" + (force (_grapheme-glyphs-promise grapheme))) (define (grapheme-string grapheme) - "Given a grapheme, construct a string representing it." - (list->string (grapheme-glyphs grapheme))) + "Return a lazily-constructed string of the glyphs in the grapheme." + (force (_grapheme-string-promise grapheme))) (define (string->grapheme-stream str) "Given a string, create a (lazy) stream of graphemes." @@ -117,8 +122,8 @@ (else (values 'any #t)))) - (define grapheme-width 0) (define glyphs-reverse '()) + (define grapheme-width 0) (define hit-eof #f) @@ -147,6 +152,8 @@ stream-null (stream-cons (make-grapheme - (reverse glyphs-reverse) - grapheme-width) + grapheme-width + ;; Delay to avoid construction of unnecessary lists and strings! + (delay (reverse-list->string glyphs-reverse)) + (delay (reverse glyphs-reverse))) (input->grapheme-stream port))))