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: reflect: add generic type arg info to reflect.Type #54393

Open
aaronc opened this issue Aug 11, 2022 · 13 comments
Open

proposal: reflect: add generic type arg info to reflect.Type #54393

aaronc opened this issue Aug 11, 2022 · 13 comments
Labels
Milestone

Comments

@aaronc
Copy link

aaronc commented Aug 11, 2022

I'm not sure if this has been discussed already (I couldn't find a prior issue), but currently reflect.Type has no direct methods to retrieve the type arguments of generic types.

The only way to retrieve these type arguments is by parsing the string returned by Type.Name() which includes fully qualified package names and could look something like this in a complex case: MyGenericType[some/package.Foo, map[string]other/package.Bar]. This string is not easy to parse because of the possibility of nested type arguments, maps, slices, etc.

I propose adding methods to reflect.Type to retrieve these type arguments programmatically:

NumTypeArg() int
TypeArg(i int) Type
@gopherbot gopherbot added this to the Proposal milestone Aug 11, 2022
@aaronc aaronc changed the title proposal: reflect: add generic type param info proposal: reflect: add generic type param info to reflect.Type Aug 11, 2022
@ianlancetaylor
Copy link
Member

I'm not sure TypeParam is the right name here. The type parameters are the parameters that appear in the type definition. I think that what you are describing is what we usually call the type arguments.

@ianlancetaylor ianlancetaylor moved this to Incoming in Proposals Aug 11, 2022
@robpike
Copy link
Contributor

robpike commented Aug 11, 2022

@ianlancetaylor Those terms are not the ones I know from my youth. We used to talk about formals and actuals, which carry a distinct meaning already. Modern computing's use of the terms parameters and arguments results in a domain-specific redefinition of true synonyms in normal English. However, I admit that redefinition is not unique to Go.

I wonder why this terminology shift happened.

@icholy
Copy link

icholy commented Aug 15, 2022

Adding methods to reflect.Type would be a breaking change.

@zephyrtronium
Copy link
Contributor

@icholy reflect.Type has unexported methods, so every type which implements it is in package reflect and can be updated along with the interface. Is there another sense in which it would be a breaking change to add methods to reflect.Type?

@ianlancetaylor
Copy link
Member

@robpike That's true, now that you mention that I remember "formal" and "actual" as well. But today even the Go spec speaks of "function parameters" and "function arguments".

@apparentlymart
Copy link

apparentlymart commented Sep 1, 2022

FWIW I also learned "formal parameters" in school but have tended to use "parameter" and "argument" in my writing for at least the last decade or so because that seems (anecdotally) to be the current familiar jargon across various different language specs and tutorials.

It is unfortunate that in plain English "parameter" and "argument" are not clearly differentiated in the way that is intended in this context, but that seems to be a common characteristic of plain words adopted as jargon. The dictionary tells me that "formal" as a noun means "an evening gown" and that "actual" isn't a noun at all, so those words don't seem to be obviously better cognates. I think it's beneficial to go with the flow here and use terms that people are likely to have encountered in other languages and in tutorials. (even though this sort of jargon evolution does make me notice my age.)

With the obvious caveat that Wikipedia is a tertiary source rather than an authority, I do note that Parameter (computer programming) mentions both pairs of terms, but gives priority to "parameter" and "argument" while relegating "formal argument" and "actual argument" to secondary position. With that said, the section Parameters and Arguments does go on to acknowledge the inconsistency of usage and potential confusion between them.


Interestingly, one of the first tutorials I found when looking for examples -- the "Functions" section of A Tour Of Go -- seems at first read to be using these terms without defining them and switching somewhat carelessly from one to the other without explaining their relationship:

A function can take zero or more arguments.

In this example, add takes two parameters of type int.

As a reader who already knows the common meanings of "arguments" vs. "parameters" I probably wouldn't noticed this if I wasn't explicitly looking for examples. Perhaps what we can learn from this example is that the terms "argument" and "parameters" are so familiar to programming language learners that explicit definition and distinguishing remarks felt unnecessary here. (I'm assuming that a non-trivial number of people have successfully learned Go in part by following this tour.)

@atdiar
Copy link

atdiar commented Sep 1, 2022

Seems about the same difference between variables and values to me.
Parameter is to variable what argument is to value.

@aaronc
Copy link
Author

aaronc commented Sep 1, 2022

Happy to switch this proposal to TypeArgument, TypeArg or even TypeActual. What do people prefer?

Does the proposal otherwise sound reasonable?

@icholy
Copy link

icholy commented Sep 1, 2022

It should probably be

NumTypeArg() int
TypeArg(i int) Type

@aaronc aaronc changed the title proposal: reflect: add generic type param info to reflect.Type proposal: reflect: add generic type arg info to reflect.Type Sep 1, 2022
@aaronc
Copy link
Author

aaronc commented Sep 1, 2022

I've changed this proposal to use TypeArg for now. That seems reasonable. Happy to change to a different naming if people prefers otherwise.

@icholy
Copy link

icholy commented Sep 1, 2022

@aaronc NumTypeArgs should be NumTypeArg to match the rest of the relect.Type methods.

@aaronc
Copy link
Author

aaronc commented Sep 1, 2022

@aaronc NumTypeArgs should be NumTypeArg to match the rest of the relect.Type methods.

Updated

@mdempsky
Copy link
Contributor

Note that if you have a local defined type declared within a type-parameterized function, then that function's type parameters are also implicit type parameters of the defined type.

For example:

func F[X any]() any {
    type T int
    return T(0)
}

then F[X].T is implicitly parameterized by X.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Incoming
Development

No branches or pull requests

9 participants