decl: Unexpected handling of "(*big.Float)(unsafe.Pointer(rv.Field(0).Pointer())).GobEncode()".
What did you do?
I typed the following input at godecl.org:
(*big.Float)(unsafe.Pointer(rv.Field(0).Pointer())).GobEncode()
What did you expect to see?
I really don't know, there's probably a few things going on here, but I at least expect it to start with "Convert X to big.Float" or similar? But I'm really unsure exactly what to expect.
What did you see instead?
(pointer to big.Float)(unsafe.Pointer(rv.Field(0).Pointer())).GobEncode()
But thanks, this'll be useful!
Thanks for reporting!
Yes, this is definitely a poor translation that can be improved. Most of what you're seeing is a Go AST -> Go syntax translation taking place, very little of it is English.
This is because I prioritized working on type declarations compared to Go statements like this.
But we can improve this, easily. It's mostly a matter of figuring out how to phrase things like type conversions, function calls, index expressions, etc.
Step one towards making progress on this issue is coming up with a good English phrase that describes the input.
It can be easier to consider simpler cases first. How do we say these in English?
x.(T)
Maybe something like assert that x has type T, or type assert x into T? Would have to make sure it cascades with other things well.
f()
Probably call f or call function f or so?
f("hello", 123)
Perhaps call function f with arguments "hello" and 123.
What about methods?
x.m("hello", 123)
Maybe call v's method m with arguments "hello" and 123? Is that reasonable?
Hmm, I just realized a bit of a problem.
Without context (i.e., a full Go program), it's impossible to tell whether this:
x(y)
Is a function call of function x with an argument y, or a type conversion of variable y to x.
It's the same syntax.
A possible workaround might be to assume that (x)(y) will be used more often for type conversions, and x(y) more often for function calls... But aside from that, I don't think there's much we can do.
A possible workaround might be to assume that (x)(y) will be used more often for type conversions, and x(y) more often for function calls... But aside from that, I don't think there's much we can do.
OK, perhaps then:
(x)(y)is a conversion ofytox.x(y)is a conversion ifxisstring,int8,int16, .... (long list of built in basic types).x(y)is either a function call or a conversion (show both possibilities), ranking function call more likely.
(x)(y) can still be a function call, it's just not commonly written Go code. But if a goal of godecl is to help translate weird, long, hard to read Go statements to English, it should probably avoid the chance of being incorrect.
But maybe that shouldn't be the goal... without full type information, it's going to be hard to be correct and succinct. Not sure, need to think about what's better (less bad).
Reference: https://play.golang.org/p/w0GOzGeXbL.
(x)(y) can still be a function call
Ah yes, I see.
if a goal of godecl is to help translate weird, long, hard to read Go statements to English, it should probably avoid the chance of being incorrect
So the way I see it, if there's two possibilities, could godecl show both (potentially with ranking), the user almost certainly knows the types and would quickly be able to distinguish the correct from the incorrect.
I think it still might be reasonable to have a whitelist of basic types you know it's very unlikely that string is a function (string)(x). But, still showing both possibilities initially could be reasonable?
Another more advanced case worth thinking through is something like:
f(g(h("hi")), e(123))
Assuming those 3 are functions, how do you pronounce that in English? It sounds... pretty awkward to say:
call f with the arguments... call g with the argument... call h with the argument "hi"... and call e with the argument 123... *phew*
Which is maybe a sign we shouldn't try to translate all parts of Go to English. What do you think? Could f(g(h("hi")), e(123)) be translated well?
To be honest, what you proposed probably sounds alright. It's a complicated call, but also isn't very realistic, I'd think you're more likely to need to tackle conversions, literals map[int]string{1:"foo"} and pointers &T. So if the above sounded a little weird, but it's technically achievable to say, I think that's good enough.
I think it'd be more natural to pronounce:
f(g(h("hi")), e(123))
As:
f of (g of (h of "hi")) and (e of 123)
But that doesn't sound as descriptive for simple calls:
fmt.Println("hello", 123)
// fmt.Println of "hello" and 123