Skip to content

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

@CosmicToast

Description

@CosmicToast

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).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions