Hi. I've been playing with gdb objects implemented as structs and have hit an oddity.
The problem can be succinctly represented by the following: scheme@(guile-user)> (port? (port-with-print-state (current-output-port))) $3 = #f I've dug into the implementation of the functions and macros involved. I think I understand why it's printing #f. A port-with-print-state is a scm_tc16_port_with_ps port, not a scm_tc7_port port. This means that any function that accepts a "port" parameter and wishes to call functions like scm_puts has to handle this distinction (because scm_puts only accepts a scm_tc7_port port). Has anyone done an audit of the C API with an eye towards making any function that claims to take a port argument accept either kind of port? The current situation is a bit confusing. E.g., in the docs for scm_set_smob_print, I see this text: It is often best to ignore @var{pstate} and just print to @var{port} with @code{scm_display}, @code{scm_write}, @code{scm_simple_format}, and @code{scm_puts}. scm_display and scm_write are smart enough to handle both kinds of ports, but scm_puts is not. I didn't check scm_simple_format. And I don't see any docs indicating one needs to be aware of this port vs port-with-pstate-port distinction in smob or struct printers. Users can be pretty simplistic when reading documentation, this user included. :-) Words tend to take on meanings that if used in one place are expected to apply everywhere. IOW, a port is a port is a port. In that vein, should port? [et.al.] return #t for a port-with-print-state port? Dunno. I dug around looking for various problems in the guile sources that might be caused by this confusion. I couldn't find any and I think it's because struct printing is the only place that uses scm_printer_apply. Every other object printer I found takes port and pstate as separate arguments and scm_prin1 handles splitting out pstate from the incoming port parameter, thus all printers will only ever see a scm_tc7_port, never a scm_tc16_port_with_ps port (and thus all printers that call scm_puts never trip over this confusion, only struct printers). In the meantime, I can make struct printers be aware of the distinction and handle being passed port-with-print-state ports. P.S. How come scm_put[cs]_unlocked are inlined in ports.h?