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

proposal: cmd/doc: add example support #26715

Open
DeedleFake opened this issue Jul 31, 2018 · 12 comments
Open

proposal: cmd/doc: add example support #26715

DeedleFake opened this issue Jul 31, 2018 · 12 comments
Labels
FeatureRequest NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@DeedleFake
Copy link

DeedleFake commented Jul 31, 2018

To go along with #25443, #25595, and #18807, it would be nice to get support for godoc's -ex flag in go doc.

@ALTree ALTree changed the title cmd/doc: Add example support cmd/doc: add example support Jul 31, 2018
@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 3, 2018
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Aug 3, 2018
@ianlancetaylor
Copy link
Contributor

ianlancetaylor commented Aug 3, 2018

CC @robpike

@robpike robpike self-assigned this Aug 3, 2018
@robpike robpike modified the milestones: Unplanned, Go1.12 Aug 3, 2018
@robpike robpike removed the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Nov 8, 2018
@ianlancetaylor ianlancetaylor added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. FeatureRequest labels Dec 7, 2018
@ianlancetaylor ianlancetaylor modified the milestones: Go1.12, Unplanned, Go1.13 Dec 7, 2018
@ianlancetaylor ianlancetaylor added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Dec 7, 2018
@ianlancetaylor
Copy link
Contributor

ianlancetaylor commented Dec 7, 2018

Punting to 1.13.

@robpike robpike modified the milestones: Go1.13, Go1.14 Jun 16, 2019
@rsc rsc modified the milestones: Go1.14, Backlog Oct 9, 2019
@rsc rsc unassigned robpike Jun 23, 2022
@nickjwhite
Copy link

nickjwhite commented Oct 18, 2022

I've recently started working on implementing this.

I'm wonder whether gating the example output behind the -ex argument is best, or whether go doc should show examples by default. I'd prefer the latter, personally, as if I'm looking up a function or whatever, chances are that if there's an example it's useful and relevant to my understanding how to use the code.

On the other hand, examples can be quite long, particularly whole file examples demonstrating a package (e.g. see the examples of sort: https://pkg.go.dev/sort).

One option could be to always show examples for specific symbols which have been requested, but not for the whole package unless -ex is passed. However that would probably be surprising behavior to most people.

Anyone have any opinions as to what would be best. If not I'll probably proceed with examples only shown when -ex is passed, as it's reasonable, but as I say I personally would prefer always printing them.

@gopherbot
Copy link

gopherbot commented Oct 24, 2022

Change https://go.dev/cl/445116 mentions this issue: cmd/doc: Add -ex flag to show examples

@DeedleFake
Copy link
Author

DeedleFake commented Oct 25, 2022

@nickjwhite

I think that examples should not be shown without the -ex flag, as usually when I'm looking something up it's a quick reference to the documentation or the ordering of the arguments and/or returns or something. I'm not usually looking for a full explanation every time, and I think it makes more sense to not show the examples by default than to require a flag to suppress them instead if they'd be annoying. That being said, I think that it should say if there are examples available, and maybe how many, if the flag isn't passed both for an entire package and when looking up a specific.

@nickjwhite
Copy link

nickjwhite commented Nov 16, 2022

Thanks for your thoughts @DeedleFake, very helpful to hear. I implemented a modified version of your suggestion in the latest change I submitted for review, based on feedback from Rob Pike. Take a look there if you're interested.

@robpike robpike changed the title cmd/doc: add example support proposal: cmd/doc: add example support Nov 22, 2022
@robpike
Copy link
Contributor

robpike commented Nov 22, 2022

Turned into a proposal to sort out the UI, which has not been settled satisfactorily through the CL.

@robpike
Copy link
Contributor

robpike commented Nov 22, 2022

There has been significant discussion in the CL about how examples would appear in go doc output, with no clear resolution.

With no -ex flag present, should the command say when examples exist?

You could put a line of commentary after the type/function/method saying there are examples, but that will get repetitive and unhelpful. The original draft was to suggest the command to get them, but that is also repetitive, repeating most of the information every time, and possibly many times in a given invocation.

You could also annotate each type with the functions that exist. That has the advantage of similarity with the rest of the output, but it too has issues. Consider bytes.Buffer:

$ go doc bytes.Buffer
package bytes // import "bytes"

type Buffer struct {
	// Has unexported fields.
}
    A Buffer is a variable-sized buffer of bytes with Read and Write methods.
    The zero value for Buffer is an empty buffer ready to use.

func NewBuffer(buf []byte) *Buffer
func NewBufferString(s string) *Buffer
func (b *Buffer) Bytes() []byte
func (b *Buffer) Cap() int
func (b *Buffer) Grow(n int)
func (b *Buffer) Len() int
func (b *Buffer) Next(n int) []byte
func (b *Buffer) Read(p []byte) (n int, err error)
func (b *Buffer) ReadByte() (byte, error)
func (b *Buffer) ReadBytes(delim byte) (line []byte, err error)
func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error)
func (b *Buffer) ReadRune() (r rune, size int, err error)
func (b *Buffer) ReadString(delim byte) (line string, err error)
func (b *Buffer) Reset()
func (b *Buffer) String() string
func (b *Buffer) Truncate(n int)
func (b *Buffer) UnreadByte() error
func (b *Buffer) UnreadRune() error
func (b *Buffer) Write(p []byte) (n int, err error)
func (b *Buffer) WriteByte(c byte) error
func (b *Buffer) WriteRune(r rune) (n int, err error)
func (b *Buffer) WriteString(s string) (n int, err error)
func (b *Buffer) WriteTo(w io.Writer) (n int64, err error)
$

There are many examples for this type:

example_test.go:17: func ExampleBuffer() {
example_test.go:25: func ExampleBuffer_reader() {
example_test.go:33: func ExampleBuffer_Bytes() {
example_test.go:40: func ExampleBuffer_Cap() {
example_test.go:50: func ExampleBuffer_Grow() {
example_test.go:59: func ExampleBuffer_Len() {
example_test.go:67: func ExampleBuffer_Next() {
example_test.go:80: func ExampleBuffer_Read() {
example_test.go:98: func ExampleBuffer_ReadByte() {

The first two are bound to the type, so you might get

func NewBuffer(buf []byte) *Buffer
    func ExampleBuffer()
    func ExampleBuffer_reader()

(I indented them for clarity, and maybe that's what should happen.) But what about all the others? They really gum up the output, with every method getting an example,

func (b *Buffer) Bytes() []byte
   func ExampleBuffer_Bytes()
<continuing like this for every method>

And in fairness, the boilerplate isn't adding much. Maybe it would be better to just annotate the default listing, like this:

func NewBuffer(buf []byte) *Buffer     <X>
func NewBufferString(s string) *Buffer    <X>
func (b *Buffer) Bytes() []byte    <X>

with some suitable symbol for <X>.

All this is just one line of inquiry. There is another option, which is to say nothing about examples by default. (I probably prefer that but am far from certain.) Having an -ex flag to trigger them is fine, but consider this plan:

The 'go doc' command excludes the tests, always. What if it sometimes didn't? Then you could ask,

$ go doc -src ExampleBytes

for instance. Or even,

$ go doc -src TestBufferGrowth

and similarly for benchmarks. That possibility should be factored into the way examples (and maybe tests and benchmarks) should be displayed.

There is too much undesigned here to jump to a CL.

@rsc
Copy link
Contributor

rsc commented Nov 30, 2022

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@hherman1
Copy link

hherman1 commented Dec 1, 2022

What if we show examples when you are looking for docs on a specific function, and otherwise never show them? Usually the go doc for a single function is pretty short so there’s room to fill and since it’s more targeted the examples are much more likely to be helpful

@nickjwhite
Copy link

nickjwhite commented Dec 1, 2022

What if we show examples when you are looking for docs on a specific function, and otherwise never show them? Usually the go doc for a single function is pretty short so there’s room to fill and since it’s more targeted the examples are much more likely to be helpful

This doesn't take into account package level examples, which do exist.

Also, just to point out that while it is often true that function level documentation is short, that's not always the case - take time.Parse for example, which prints 48 lines in total, and the associated example for it is 51 lines (including output). This is unusual, but is not unprecedented. That said, I do personally agree with you that always printing examples when doing go doc pkg func would be my preference. When I'm looking up specific documentation, an example is a useful component of that.

@nickjwhite
Copy link

nickjwhite commented Dec 1, 2022

With no -ex flag present, should the command say when examples exist?
...
There is another option, which is to say nothing about examples by default. (I probably prefer that but am far from certain.)

I definitely think that some pointer to there being executable examples available is important. I don't want to run go doc bufio ScanBytes, and think "I could do with an example, I'll try -ex," then do that and be met with no output. That's not a good user experience.

I've been using the version I wrote for the CL day-to-day over the past week, where the text "There are executable examples for " is added to the end of the documentation, which I've found to be perfectly good, and not too annoyingly repetitive.

You could also annotate each type with the functions that exist. That has the advantage of similarity with the rest of the output, but it too has issues. Consider bytes.Buffer:

I don't mind there not being hints that particular functions or types have examples until the precise one is looked up. I think there's no neat way to do this; every option "gums up" things too much, even just annotating the listing like you gave examples for.

The 'go doc' command excludes the tests, always. What if it sometimes didn't? Then you could ask,

$ go doc -src ExampleBytes

Interesting idea, but I think it's a bit less clear & discoverable than showing the example(s) associated with a regular identifier, particularly given that there can be several examples for an identifier. Consider go doc -ex bufio Scanner versus go doc bufio ExampleScanner_emptyFinalToken.

Overall I prefer something close to what's currently in the CL. But I am a little biased (as well as inexperienced), as it's my first contribution to Go, so take what I suggest with an appropriate grain of salt. That said, I chose this issue to start on as I always hated that there was no way to get examples from the command line, and I use go doc all the time, so I am motivated to get a good solution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FeatureRequest NeedsFix The path to resolution is known, but the work has not been done.
Projects
Status: Active
Development

No branches or pull requests

7 participants