Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom print method for object-like tables and structs. #1543

Open
CosmicToast opened this issue Jan 6, 2025 · 1 comment
Open

Custom print method for object-like tables and structs. #1543

CosmicToast opened this issue Jan 6, 2025 · 1 comment

Comments

@CosmicToast
Copy link
Contributor

Similar to #73, but for tables and structs with prototypes.

Motivation: I'm currently implementing a numerical tower for Janet.
I have my bigints (in Z) implemented as a C abstract type, but with very few abstractions and no polymorphism.

The plan was to implement rationals and complex numbers as an object-like: {:n numerator :d denominator :in imaginary-numerator :id imaginary-denominator}.
The interest is that I can implement polymorphic features in Janet, where it's much easier to do than in C, while leaving direct access to the underlying C implementation available as a separate module.

The problem being solved is that currently, both (string num) and (describe num) (and by extension, all uses of printf-likes) are useless, which means I can't integrate the bignums in a way that would "feel" native (I'm aiming for a DX where a naive end-user doesn't need to think about whether they're using bignums or regular numbers, the tradeoff being purely in performance vs precision).
I'm open for suggestions for the best way to resolve this as a whole (worst-case scenario, I'll implement the whole thing as a wrapping C abstract type, but that would be rather unfortunate :)).

In the meanwhile, a change that I think would at least somewhat help me get going, and would be useful for the project as a whole, is the aforementioned.
If abstract numbers are allowed to override pretty printing / describe / string, why not true Janet "objects"?
It's already possible to influence them via :_name.

A few designs are possible. We can have a flat (so not proto-exclusive) :string (or similar, like :describe) message, like the current support for :+ and :r+. Alternatively, we can follow :_name with :_string on proto-only.
I took a quick look at implementing it as a new case of core/pp.c::janet_to_string_b, but I'm not sure if calling a JanetFunction like that would be safe (from what I recall the VM is not reentrant, and that would look oddly similar to reentrancy to me; what if the string function calls (repl), eh?).
Instead of jumping into implementing this (which might be the wrong approach), I figured I'd open an issue first to double as a discussion point (for both this and the overall abovementioned use-case; it would be really nice if language additions as modules could feel as native as possible).

@CFiggers
Copy link

CFiggers commented Jan 6, 2025

I would also be very interested in this. I have a couple different small libraries that essentially provide "Native abstract types" by way of prototypes on standard Janet tables/Janet structs. It would be fantastic to be able to have a custom pretty printer for them.

For e.g., if I have a (Janet) table that represents tabular data using key = header, value = column of data, I would like to have pp render that (Janet) table in a format that resembles a markdown table.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants