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

fmt: consider altering %#v behaviour to include type information for simple types #6565

Closed
kortschak opened this issue Oct 11, 2013 · 16 comments
Closed
Assignees

Comments

@kortschak
Copy link
Contributor

@kortschak kortschak commented Oct 11, 2013

Suggestion is to make %#v output type information when formatting simple types, e.g. var
f float64 = 1 would be formatted as "float64(1)" rather than "1" as
it is now.

This gets complicated when looking into composite types; presumably under this approach
the type annotation for array/slice/map elements/keys should be elided to match the
elision rules for valid Go syntax, but composite fields should still have their type
shown.

There are obvious potential compatibility issues with change.

https://groups.google.com/d/topic/golang-nuts/0uloMvaQBYY/discussion
@cznic
Copy link
Contributor

@cznic cznic commented Oct 11, 2013

Comment 1:

%#v means "a Go-syntax representation of the value" [0]. But Go-syntax representation of
int(1) is '1', not 'int(1)'. Even though the later is valid, the former is the
default/standard in idiomatic Go source code.
#WorkingAsIntended or at least #Unfortunate
PS: Yes, it would broke some of my own _test files.
  [0]: http://golang.org/pkg/fmt/
@adg
Copy link
Contributor

@adg adg commented Oct 11, 2013

Comment 2:

Labels changed: added priority-later, removed priority-triage.

Owner changed to @robpike.

Status changed to Thinking.

@kortschak
Copy link
Contributor Author

@kortschak kortschak commented Oct 11, 2013

Comment 3:

Re:#1 That's why I picked float64 as the example type. A float64 does not print "1."
with %#v, which would be the idiomatic way of assigning 1 to a float64. The rest? What
about this, http://play.golang.org/p/vkOtAbL7s0. That's a lot of missing type
information that would be required for Go syntax representation of the relevant values 1.
It may not be fixable now, but it is at the very least unfortunate.
@cznic
Copy link
Contributor

@cznic cznic commented Oct 11, 2013

Comment 4:

@3 Go-syntax != {valid,complete}, compiler grade Go source code. {float64(1.0),int8(1))
printed as '1' is a correct behavior - 1.0 is exactly same as 1 in IEEE representation
and int8(1) is exactly the same value etc.
If one need more {debug,test} info, "%T(%#v)" is usable today (and is one of the sources
of backward incompatibility introduced by the proposal).
@kortschak
Copy link
Contributor Author

@kortschak kortschak commented Oct 11, 2013

Comment 5:

> Go-syntax != {valid,complete}, compiler grade Go source code.
No, this is absolutely true, but Go syntax as a fmt option aids by giving type
information in all other cases. You could have a Go syntax formatting that gave unnamed
definitions of all composite type - but we don't have that.
> {float64(1.0),int8(1)) printed as '1' is a correct behavior - 1.0 is exactly same as 1
in IEEE representation and int8(1) is exactly the same value etc.
I don't believe you can make a claim for correctness or otherwise here; it comes down to
a design decision. 1.0 make well be exactly the same value as 1, but 1. or float64(1)
give this type information, but this doubles up that information in cases where the type
is not a simple type, e.g. http://play.golang.org/p/oeFhSO8_b7 So now we have an
approach that is not truly general (an break in symmetry is often - maybe in this case -
an indication of a design mis-step and something that is often raised when people
discuss Go design principles).
> If one need more {debug,test} info, "%T(%#v)" is usable today (and is one of the
sources of backward incompatibility introduced by the proposal).
The first part is addressed above, but I don't understand how this particular thing is
any more of a backward incompatibility that any other use of %#v where people are
comparing against expected values. Note that I did raise the compatibility issue in the
initial ticket. I see this as a Go2-if-ever issue.
What initially spurred this was that if you have a type F float64, %#v does not format
that differently to float64, yet there was some intention in the definition of F, so why
not reflect that.
@kortschak
Copy link
Contributor Author

@kortschak kortschak commented Oct 11, 2013

Comment 6:

It's been pointed out to me that if the argument that changing %#v behaviour is taken to
its logical extension, changing (in any way) the fields of a struct that does not
implement fmt.{Stringer,Formetter} would be breaking the compatibility promise since the
output with %#v (and many other verbs for that matter) would be changed.
@robpike
Copy link
Contributor

@robpike robpike commented Oct 11, 2013

Comment 7:

It might have been nice to consider this early on, but it wasn't thought of then and now
seems hard to do without breaking expectations in all but the simplest examples. Marking
"will not fix".

Status changed to WontFix.

@kortschak
Copy link
Contributor Author

@kortschak kortschak commented Oct 11, 2013

Comment 8:

Any chance of Go2 tag rather than WontFix?
@robpike
Copy link
Contributor

@robpike robpike commented Oct 12, 2013

Comment 9:

I've come to think it's not a good idea, at least as expressed here.
@kortschak
Copy link
Contributor Author

@kortschak kortschak commented Oct 12, 2013

Comment 10:

No worries. Thanks for the consideration.
@btracey
Copy link
Contributor

@btracey btracey commented Oct 15, 2013

Comment 11:

Sorry to dig up this issue, but how about printing the type for non-simple types, but
keep the current behavior for built-in types? So 
    foo := 1
    fmt.Printf("%#v", foo) 
would just print 1
but
    type Mytype int
    foo := Mytype(1)
    fmt.Printf("%#v", foo)
would print main.Mytype(1)
@minux
Copy link
Member

@minux minux commented Oct 16, 2013

Comment 12:

i'd suggest you use a dedicated debugging print library for that purpose (like go-spew).
@robpike
Copy link
Contributor

@robpike robpike commented Oct 16, 2013

Comment 13:

fmt.Printf("%T(%[1]v)", 1.0)
@kortschak
Copy link
Contributor Author

@kortschak kortschak commented Oct 16, 2013

Comment 14:

%T(%[1]v) is not the same as the proposed behaviour for all interface{} as described
above - composite, array/slice, and map types already lead with the type - nor is spew
since it give much more type information.
@robpike
Copy link
Contributor

@robpike robpike commented Oct 16, 2013

Comment 15:

It does what you want for the case that triggered the discussion.
Please let it go, the issue is closed. Minux's suggestion is the way to deal with this.
@kortschak
Copy link
Contributor Author

@kortschak kortschak commented Oct 16, 2013

Comment 16:

Sorry, while I have absolutely let the issue go and don't expect it to be fixed, that is
a misreading of the original issue.
@golang golang locked and limited conversation to collaborators Jun 25, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
7 participants
You can’t perform that action at this time.