So, I have had a look and played around with trimmed/lazy and it does nothing fancy. It relies solely on guiles own procedures for custom printers, which means we get guile's guarrantees for free. Recursive records are no problem, nor are circular lists of any rank or vectors any problem.
trimmed/lazy is also well-behaved when printing circular lists/vectors. (show #t (trimmed/lazy 100 (each-in-list (circular-list 1 2 3 4)))) works just fine and displays 1 2 3 4 ... until the 100 character limit is met. I will have to do some porting to delimited continuations or CPS because currently it is relying on call/cc and the overhead is quite noticeable. -- Linus Björnstam On Sun, 16 Jun 2019, at 21:35, Mark H Weaver wrote: > Hi John, > > John Cowan <co...@ccil.org> writes: > > > On Sun, Jun 16, 2019 at 2:47 AM Mark H Weaver <m...@netris.org> wrote: > > > > > >> How do you implement 'written-shared', 'pretty-shared', and > >> 'trimmed/lazy'? In particular, how do you avoid non-termination when > >> asked to print cyclic data, when the cycle includes a non-standard data > >> type printed using a custom printer? For example, what if you print a > >> list that includes an object whose custom printer will print output that > >> includes the same list that you started with? > >> > > > > Of course it can't cope with that. But consider an object whose custom > > printer outputs its instance variables where one of those instance variables > > has been assigned to the object itself. No procedure other than the object > > printer itself is going to be able to break *that* loop. > > The built-in 'write' and 'display' procedures can break the loop, which > is the approach that I chose when I last looked at this. > > Regards, > Mark > >