Hi!
My use case for this was to basically have a formatter for titles that
would also save those in the fmt-properties, so that they can be used to
generate a table of contents later. That works only as long as there
are no titles within a columnar formatter. I thought it'd be nice to
use the formatter state properties for that instead of relying on
something like a global make-parameter variable.
(I also noticed that fmt-capture also behaves in the same way, in that
the state of the producer is separate from the consumer.)
I suppose my current use could be changed to use something like doing
two passes over the formatter functions, once to get all of the metadata
(and then explicitly not calling something like `columnar`) and another
time for the actual layout. But to me it seemed like it would make
sense that at least the fmt-properties would be preserved.
I get that you don't want to keep all of the formatter state in the
original state, as that would mess up the output, but to me it seemed
like the properties would be sensible to keep.
Cheers
Nik
On 1/15/26 1:40 PM, Alex Shinn wrote:
Hi Niklas,
Thanks for the proposal!
The current behavior is intentional.
The columns are generated independently, interleaved,
and as each line is available it's output, updating orig-st.
Updating orig-st with the result of each column would
break the row/col numbers. What you propose instead is
not updating the full state, but just the non-standard
properties. I tend to think these should not persist beyond
their columns, but did you have a particular use case in
mind that wasn't behaving as expected?
--
Alex
On Wed, Jan 14, 2026 at 11:07 PM Niklas Böhm via Chicken-hackers
<[email protected] <mailto:[email protected]>> wrote:
Hello everybody, hello Alex,
I noticed that when using `columnar` that changes to the format state
get swallowed. Digging into this, it's due to the copying of the state
before creating partial output from the following lines (fmt-
column.scm,
l. 82f):
;; gen threads through it's own state, ignore result
(gen (fmt-set-writer! (copy-fmt-state st) output*))
All of the changes to `st` within the gen function will then ignored.
Now I am not exactly sure which changes we want to preserve, but I
believe that at least the `properties` should be kept, as they might
contain meaningful information (which is how I discovered this bug).
Would it make sense to preserve more information from the copied state
or should we leave it at that? Currently my fix (also attached)
looks like:
;; gen threads through it's own state, copy over properties
(let ([st (gen (fmt-set-writer! (copy-fmt-state st) output*))])
(fmt-set-properties! orig-st (fmt-properties st)))
Let me know what you think, would be happy to see this included.
Cheers
Nik