Is it possibile to get method parameter name by reflect

4,418 views
Skip to first unread message

microhelper

unread,
Jun 7, 2012, 6:41:33 AM6/7/12
to golang-nuts
Dear all,

Is it possibile to get method parameter name by reflect?

example

there is a method

func (u *user)query(name string, age int) []user {
...
}

http request is : get /api/query?&name=foo&age=18

I want to extract args value from query string and invoke query dynamic

microhelper

unread,
Jun 7, 2012, 6:40:33 AM6/7/12
to golang-nuts

Kyle Lemons

unread,
Jun 7, 2012, 7:54:37 PM6/7/12
to microhelper, golang-nuts
See runtime.Caller (and FuncForPC) if you want the name of your current method or any of your callers.

Kyle Lemons

unread,
Jun 7, 2012, 7:56:01 PM6/7/12
to microhelper, golang-nuts
Oh, sorry, I somehow missed the "parameter" qualifier in your initial email.  No, I do not believe there is any way to get this.  If you take an object as a parameter, you could extract the names of its fields, but that is about as close as you can get without parsing the source I suspect.

Cole Mickens

unread,
Jun 7, 2012, 8:10:21 PM6/7/12
to golan...@googlegroups.com
I don't think you'd be able to do that anyway. How would you handle:

/api/query?&name=foo&age=18
/api/query?&name=foo&weight=18  

The proposed handlers would have the same method signatures, no?

Dianming Song

unread,
Jun 7, 2012, 9:17:17 PM6/7/12
to Kyle Lemons, golang-nuts
Thanks

that's sad.

I am developing a web MVC framework,  this feature is very useful to help programmer develop web application in straight simple way.




2012/6/8 Kyle Lemons <kev...@google.com>

Kyle Consalus

unread,
Jun 7, 2012, 10:37:46 PM6/7/12
to Dianming Song, Kyle Lemons, golang-nuts
You can get something similar (and, for some cases, slightly better) using Gorilla's schema package.
However, it requires you to use a struct parameter with named fields.

Here's a hacky toy example:

Dianming Song

unread,
Jun 7, 2012, 10:59:32 PM6/7/12
to Kyle Consalus, golang-nuts
thank you for advice, it works.

it means I need to define parameter struct for every single action method, quite a lot.
it's different with other programming language, c#, rails, ..., why golang does not add something like paramterType in reflect package?

anyway, I will change my web framework design


2012/6/8 Kyle Consalus <cons...@gmail.com>

Rob 'Commander' Pike

unread,
Jun 8, 2012, 12:50:02 AM6/8/12
to Dianming Song, Kyle Consalus, golang-nuts
Why not use a map?

-rob

Dianming Song

unread,
Jun 8, 2012, 1:30:59 AM6/8/12
to Rob 'Commander' Pike, Kyle Consalus, golang-nuts
yes, map is another option, but programmer need to write code to convert string to int, float, time ... 

my origin design is the  web framework can  handle route, cache, session, auth, gzip and so on, programmer just need to focus on api
web framework invoke api and render result.

example

package "webapi"

type UserControler struct {
}

//convert []user to json, xml or jsonp accoring to request header:accept
func (*UserControler) Query( name string, age int) []user{
    return []User{...} 
}

//render html with help of view eigne (html/template, mustache ... )
func (*UserControler) Home( id int) HttpResult{

    ...
    return gomvc.View(...)  
}

//render []byte as jpg/png 
func (*UserControler) Avator( id int) HttpResult{
    ...
    return gomvc.Image()
}

//render []byte as a  a attachment file 
func (*UserControler) Download( id int)  HttpResult{
    ...
    return gomvc.FileStream(xxx)
}

//HttpResult is a interface


2012/6/8 Rob 'Commander' Pike <r...@golang.org>

Kyle Lemons

unread,
Jun 8, 2012, 1:15:37 PM6/8/12
to Dianming Song, Kyle Consalus, golang-nuts
If you try to design a framework the same way it would be designed in a dynamic language, you will find the go offering "lacking."   I suspect the opposite would also be true.

A better question to ask might be "I would like to design a framework that allows me to automatically dispatch HTTP requests to /api/handler?some=val to a handler and break out the parameters automatically.  What are some idiomatic ways I could accomplish that?" or whatever the question underlying your current inquiry is.  Asking these sorts of questions will probably be a lot more educational and have a better chance of sparking a constructive discussion :).

Dianming Song

unread,
Jun 20, 2012, 12:09:26 AM6/20/12
to Kyle Lemons, golang-nuts, Rob 'Commander' Pike
Thanks for all advice, I adjust design and publish v0.1 on github  https://github.com/sdming/gomvc

demo

please check out 

or  test api with jquery 

cd xxx/gomvc/example
go run app/user_server.go

2012/6/9 Kyle Lemons <kev...@google.com>

Rasmus Schultz

unread,
Dec 20, 2013, 5:04:39 PM12/20/13
to golan...@googlegroups.com, Kyle Lemons, Rob 'Commander' Pike
This reply is 1.5 years old - is the answer still up to date?

Function argument names still are not available at run-time in any way?

Makes me want for a feature I've missed in other languages over the years: that the set of arguments for any function implicitly had a type... (e.g. in Go's case a struct-type where each field corresponds to an argument.)

Rémy Oudompheng

unread,
Dec 21, 2013, 2:42:32 AM12/21/13
to Rasmus Schultz, golang-nuts, Kyle Lemons, Rob 'Commander' Pike
On 2013/12/20 Rasmus Schultz <ras...@mindplay.dk> wrote:
> This reply is 1.5 years old - is the answer still up to date?

Yes.

Rémy.

Walter Schulze

unread,
May 12, 2014, 8:34:59 AM5/12/14
to golan...@googlegroups.com, Rasmus Schultz, Kyle Lemons, Rob 'Commander' Pike
I would also find this feature useful.

I am trying to design a "query" language which is easily extendible, which implies a register pattern with lots of reflect.
Parameter names would make my generated documents much more usable.

tjholo...@gmail.com

unread,
Oct 7, 2014, 10:49:50 PM10/7/14
to golan...@googlegroups.com
Damn, I wanted this for self-documenting RPC, still not possible?

Matt Harden

unread,
Oct 8, 2014, 12:10:02 AM10/8/14
to tjholo...@gmail.com, golang-nuts
It's still not possible, and I wouldn't count on it ever being possible. There is currently no reason for the compiler to store the names of function args in the compiled code. It doesn't keep the function name either, for that matter.

You could write a code generator that works with go generate (1.4+ only - not released yet) which could read the declaration and create the implementation automatically for you. go/ast can help you with this. This could also eliminate any slowdown due to reflection.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rasmus Schultz

unread,
Oct 8, 2014, 7:34:32 AM10/8/14
to Matt Harden, tjholo...@gmail.com, golang-nuts
> There is currently no reason for the compiler to store the names of function args in the compiled code

You must mean, besides reflection? :-)

>  It doesn't keep the function name either, for that matter.

It doesn't? Then how does this work:


Field names are available:


So it would seem argument names may be the exception that confirms the rule ;-)

If what you're saying is the compiler doesn't need this information for itself, that may be true - but it would be nice, for the sake of completeness and consistency in the reflection API, if the names of arguments could be reflected, same as the names of most other members.

To be fair, const names can't be reflected - but arguably, these are just symbols and not members per se - arguments do appear to be the only member type that cannot be reflected?

It seems incomplete without it.


--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/nM_ZhL7fuGc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.

Jan Mercl

unread,
Oct 8, 2014, 7:48:49 AM10/8/14
to Rasmus Schultz, Matt Harden, tjholo...@gmail.com, golang-nuts
On Wed, Oct 8, 2014 at 1:34 PM, Rasmus Schultz <ras...@mindplay.dk> wrote:
> If what you're saying is the compiler doesn't need this information for
> itself, that may be true - but it would be nice, for the sake of
> completeness and consistency in the reflection API, if the names of
> arguments could be reflected, same as the names of most other members.

I don't think it would be nice. It would, perhaps substantially,
inflate the size of every executable when only rarely needed.

However, If really desired, regardless of me thinking such need is
questionable, embed the source part as a string constant ("//go:
generate") and in init() parse it and produce some mapping from
fnName, argName -> argIndex.

-j

Rasmus Schultz

unread,
Oct 8, 2014, 7:59:38 AM10/8/14
to Jan Mercl, Matt Harden, tjholo...@gmail.com, golang-nuts
Okay, valid - but how come this concern applies to arguments names and not to field and function names?

Dart addresses this problem by making reflection entirely opt-in, maybe that's something to consider - a file-level directive of some sort to enable reflection. Usually developers know whether or not they need/want something to be reflected, since it's usually a means of integrating with some service or helper that consumes the metadata.

This would address your concerns about binary footprint even better, right? You could optimize away all redundant metadata. And perhaps additionally this could make it harder to reverse code, which is probably less of a concern for e.g. models or "plugins" that deliberately expose metadata for other components to consume via reflection.

Of course making reflection opt-in would be a BC break, but a fairly small one, forcing developers to take a position and decide whether each file should be reflected or not.

Jesper Louis Andersen

unread,
Oct 8, 2014, 8:02:17 AM10/8/14
to Rasmus Schultz, Matt Harden, tjholo...@gmail.com, golang-nuts
On Wed, Oct 8, 2014 at 1:34 PM, Rasmus Schultz <ras...@mindplay.dk> wrote:
It doesn't? Then how does this work:


Technically, this is a way to get methods out of values. A "function" is a different thing than a method, and it probably has a different representation at runtime. So in this case, it was relatively easy to reflect on the methods (because there is a table of methods for values which you can search through). However, doing the same reflection on functions requires you to have a table of all function names at runtime. Which is quite uncommon to have in many compilers.


--
J.

Rasmus Schultz

unread,
Oct 8, 2014, 8:06:33 AM10/8/14
to Jesper Louis Andersen, Matt Harden, tjholo...@gmail.com, golang-nuts
>  However, doing the same reflection on functions requires you to have a table of all function names at runtime. Which is quite uncommon to have in many compilers.

Sure, but it's also a frequently asked question - I've seen developers asking for the same thing in Java and C# for example, often resorting to things like actually deploying metadata files for debugging; I've had to do that myself in C# in the past.

Not pretty, but it was that or a bunch of redundant code - once you start to rely on reflection, it gets frustrating when you realize it's incomplete and can't take you all the way to the finish line.

I think Dart has the right answer - make it opt-in. You get the best of both worlds then - a small footprint by default, and full-scale reflection only when and where you deem necessary.

Jesper Louis Andersen

unread,
Oct 8, 2014, 8:22:55 AM10/8/14
to Rasmus Schultz, Matt Harden, tjholo...@gmail.com, golang-nuts

On Wed, Oct 8, 2014 at 2:06 PM, Rasmus Schultz <ras...@mindplay.dk> wrote:
I think Dart has the right answer - make it opt-in.

Dart, as a system, is built around the idea of runtime introspection, much in the same way Javascript is. The JIT method allows Dart to delay optimizations until runtime, which makes it possible to satisfy a lot of these queries at runtime. You need the information anyway. In languages with more traditional compilation schemes, like Go, you have to make decisions at compile time about the representation of data.

A function which exists in your program might not even exist in the produced binary due to inlining. This is a good thing(tm), because it leads to faster code in many cases and allows the programmer freedom in structuring the program, without having to worry about function call overhead[0]. But it also makes reflection on the function impossible as a result, and since reflection is a string at runtime, we can't make this safe in any way. In Dart, where we can delay the optimization decision until runtime and we have a deoptimizer in addition, this can be solved: If we reflect on something which has been optimized away, we can deoptimize that part of the code path.

The price you pay for a Dart solution is complexity. And it is not at all clear this added complexity is worth the effort.

In a system like Go, you would probably want to handle this at compile-time. It is more in the spirit of what Go's compilation model, I think.

[0] Inlining decisions are complex beasts. On one hand, it eliminates some stack movement, register saves and checking, which makes code run faster. On the other hand, it increases the code size which pressures the instruction cache to a larger extent. A good compiler will balance the decision to inline or not based on many factors. Also note that inlining often exposes other optimizations so it is not a clear-cut decision. Polyvariant inlining, where each call site is individually considered for inlining, is where the cool kids are today, but this is usually really hard to pull off since the optimization becomes "on-line" with other optimizations.


--
J.
Reply all
Reply to author
Forward
0 new messages