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

Printer feature #238

Merged
merged 9 commits into from
Sep 8, 2021
Merged

Printer feature #238

merged 9 commits into from
Sep 8, 2021

Conversation

warpfork
Copy link
Collaborator

@warpfork warpfork commented Sep 2, 2021

I've started developing a printer feature, which provides a human-readable debugging output describing a tree of nodes.

This is an answer to #88 .

  • ✔️ It's reasonably human readable, and rich in information.
  • ✔️ It can describe typed or untyped data, or a mixture of it.
  • ✔️ Everything works generically over the datamodel.Node interface, and feature-detects schema.TypedNode as appropriate.
  • ✔️ No additional methods are needed from nodes.
  • ✔️ There are a number of configuration options already (and probably more are desired).
  • 🚱 Nongoal: it's not a codec. It's not intended to be parsable! (This is important: I want this to provide more information than data model alone, which means it's definitionally not a codec.)
  • 🤷 Does not currently log anything about the node implementation type (e.g. bindnode vs basicnode vs custom/codegen'd). We could add this in the future if it seems useful?
  • 🤷 It's not standardized. (I don't see any reason to aggressively push this to be a cross-language thing. If it evolves well and seems desirable? Okay, sure. But we don't need to start there.) On the plus side: that also means it's not frozen to this format.

The syntax is somewhat impulsively chosen. Roughly, it's kindname{"value"} (so: string{"foo"} and int{12} and bool{true} etc), or for typed information, typekindname<TheTypeName>{"value"}. You can check out the tests for a few more examples of how it looks. We could bikeshed this syntax, I suppose, but so far, I'm finding it tolerably readable.

I've started using this in debugging myself already as I work using go-ipld-prime as a downstream user in other projects, and it's saving me tons of time, and also starting to show up in my docs there to explain features to people. I'm pretty happy about it. (Also: it means I'm already relatively attached to some of these commit hashes and will try to roll forward and resist a need to rebase if possible.)

In the future, I'd like to add some functions to the root ipld package which call these printer features, for rapid easy use and for discoverability, but that's not included in this PR yet.

Review welcome. This seems like the sort of thing I'd rather merge relatively quickly, and continue iterating on master, though.

n := bindnode.Wrap(&FooBar{"x", "y"}, ts.TypeByName("FooBar"))
qt.Check(t, Sprint(n), qt.CmpEquals(), wish.Dedent(`
struct<FooBar>{
foo: string<String>{"x"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string<String> is getting weird, I don't suppose it's reasonable to special-case the typed data model kinds like String to omit the typing here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm on the fence on this. At first I thought I'd strip it, as you suggest. Then I looked at the printout the first time I got one to come out, and was like... hum: typed vs untyped string seems like the kind of distinction that could actually trip someone up someday, so maybe that's useful.

I'm still on the fence, a couple days later. I can't think of how typed-vs-untyped string would trip someone up, exactly, either. It's just a nagging fear.

Maybe a config option for "SmartElidePreludeTypeInfo bool"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd propose we leave it in verbose mode for now, someday add that config flag, and then if enough people are perturbed by the verbosity we flip the default of that flag to true. We should probably get some impressions from people further out from us before deciding to elide things that might be obvious to us but nonobvious to new users, is my thinking.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a config placeholder for this and attached documentation for it so someone looking for such a feature can at least find that we've considered it. Haven't implemented it immediately, however.

printer/doc.go Outdated
}
"unit types": unit<TheTypeName>
"notice unit types": "have no braces at all, because they have literally no further details. they're all type info."
"variants": variant<TheUnionName>{string<TheInhabitant>{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so variant is the name for "specific variant of a union"? introduction of new terminology is a concern I reckon, it doesn't read as smoothly if there's disconnect with user-consumed schema lingo

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh oof, I should s/variant/union/ this. It's a stretchmark from how I think during development: I was trying out "variant" as an alternate name for "union" and trying to get a feel for if I liked it when seeing and using it for a while.

The result is "yes", I do kinda come to prefer that term. I think maybe we should consider doing a mass rename of "union" to "variant".

But that's not a discussion I want to force through in this PR; it deserves its own space.

@rvagg
Copy link
Member

rvagg commented Sep 3, 2021

I think I prefer string{"x"} to the shorthand version you're proposing in here; I'd advocate dropping that option entirely

aside from comments left inline, I think I like this. I did something a little bit similar in a JS experiment I was working on but this reads much better and you've integrated type information which is great, so I might have to copy this.

@warpfork
Copy link
Collaborator Author

warpfork commented Sep 3, 2021

🙌 I'm thrilled you like it.

And you're right, I think string{"x"} consistently is a good idea too now. I'll remove the references to the shorthand idea.

The defaults and what we are explicit about is rather different
(mostly, more) than what I originally expected.  Bring the example
back in line with where the implementation actually ended up.

(We *are* going to make strings annotated by default, per review:
#238 (comment) )
…e config option.

'ElidePreludeTypeInfo' originates from code review discussion:
#238 (comment)
@warpfork
Copy link
Collaborator Author

warpfork commented Sep 8, 2021

Though this contains some TODOs, I'm going to go ahead and merge it. Since this seems directionally acceptable, it should be no problem to add the remaining features in subsequent PRs.

(I've gotten myself in the awkward position of wanting both this, and some other features recently landed, at the same time, in a downstream, and yet don't have the time block today to finish the remaining feature wishlist in this diff. So: onward!)

@warpfork warpfork merged commit 5c5feb6 into master Sep 8, 2021
@warpfork warpfork deleted the printer-feature branch September 8, 2021 15:32
@aschmahmann aschmahmann mentioned this pull request Sep 30, 2021
62 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants