Can I pass the method as parameter to another function ?

8,295 views
Skip to first unread message

davy zhang

unread,
Mar 5, 2013, 2:48:53 AM3/5/13
to golan...@googlegroups.com
here is the code


prog.go:50: method t.Year is not an expression, must be called

David DENG

unread,
Mar 5, 2013, 3:43:49 AM3/5/13
to golan...@googlegroups.com
  1. If you want to reference that method as a function, use time.Time.Year
  2. Its type is func(time.Time) int, not func() int
David

Kevin Gillette

unread,
Mar 5, 2013, 3:46:44 AM3/5/13
to golan...@googlegroups.com
The language may eventually allow curried method expressions, but for right now, they're not legal. You may pass a normal method expression, such as shown at: http://play.golang.org/p/URL115raiJ

In this case, the method expression yields a func signature with the receiver type as the explicit first argument.

davy zhang

unread,
Mar 5, 2013, 3:48:23 AM3/5/13
to David DENG, golan...@googlegroups.com
Yep, you'r right, I updated my code as you said, but still has compiler complains, thanks

http://play.golang.org/p/dJbJAtLboA


--
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/o2Q5oc36Qt0/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Rémy Oudompheng

unread,
Mar 5, 2013, 3:49:43 AM3/5/13
to davy zhang, David DENG, golan...@googlegroups.com
On 2013/3/5 davy zhang <davy...@gmail.com>:
> Yep, you'r right, I updated my code as you said, but still has compiler
> complains, thanks
>
> http://play.golang.org/p/dJbJAtLboA

What do you not understand in the compiler message? If it is not
clear, it should be improved.

Rémy.

davy zhang

unread,
Mar 5, 2013, 3:51:40 AM3/5/13
to golan...@googlegroups.com
Thanks a lot for the correction,

but if the method delared as 
(t *time) func Year(){
...
}
this workaround won't  compile, am I right?

David DENG

unread,
Mar 5, 2013, 3:53:26 AM3/5/13
to golan...@googlegroups.com
func (t *time) Year() {
}

the receiver follows keyword func.

David

David DENG

unread,
Mar 5, 2013, 3:54:54 AM3/5/13
to golan...@googlegroups.com
I have no idea of what your design is for, but another alternative way to make your program compiled is to use closure:


David

davy zhang

unread,
Mar 5, 2013, 3:55:41 AM3/5/13
to golan...@googlegroups.com, davy zhang, David DENG
method t.Year is not an expression, must be called

the error is the same as the first version, but Deng did help me out about the type definition.

thanks for that

David DENG

unread,
Mar 5, 2013, 3:56:27 AM3/5/13
to golan...@googlegroups.com, davy zhang, David DENG
Some suggestion like `Use Time.Year instead` may help.

David

On Tuesday, March 5, 2013 4:49:43 PM UTC+8, Rémy Oudompheng wrote:

davy zhang

unread,
Mar 5, 2013, 4:07:30 AM3/5/13
to golan...@googlegroups.com, davy zhang, David DENG
Thanks, this is another way to do it, and can be used as common idiom

Zizon Qiu

unread,
Mar 5, 2013, 4:12:31 AM3/5/13
to davy zhang, golang-nuts
you may wrap it in a clause.
like: fc.update( func() int(return t.Year()},...)

sounds like function is not truly first class citizen here.


--
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.

Rémy Oudompheng

unread,
Mar 5, 2013, 4:18:02 AM3/5/13
to Zizon Qiu, davy zhang, golang-nuts
On 2013/3/5 Zizon Qiu <zzd...@gmail.com> wrote:
> you may wrap it in a clause.
> like: fc.update( func() int(return t.Year()},...)
>
> sounds like function is not truly first class citizen here.

I don't understand what makes you say that. The issue is that t.Year
is not a function.

Rémy.

davy zhang

unread,
Mar 5, 2013, 4:25:19 AM3/5/13
to golan...@googlegroups.com, Zizon Qiu, davy zhang
Yes, the issue is "t.Year is not a function", but the question is how can I pass t.Year into another function as parameter, so the follow up post solved this problem include zizon Qi
1. Wrap it as a closure 
2. Use time.Year as parameter not the instance method

Zizon Qiu

unread,
Mar 5, 2013, 4:39:23 AM3/5/13
to Rémy Oudompheng, davy zhang, golang-nuts
what if t.Year is an `attribute`.
like in javascript or something equivalent.

it is legal to use t.Year as an expression whatever it is.

Jan Mercl

unread,
Mar 5, 2013, 4:42:24 AM3/5/13
to Zizon Qiu, Rémy Oudompheng, davy zhang, golang-nuts
On Tue, Mar 5, 2013 at 10:39 AM, Zizon Qiu <zzd...@gmail.com> wrote:
> what if t.Year is an `attribute`.
> like in javascript or something equivalent.
>
> it is legal to use t.Year as an expression whatever it is.

http://golang.org/ref/spec#Method_expressions

-j

Nate Finch

unread,
Mar 5, 2013, 7:57:19 AM3/5/13
to golan...@googlegroups.com
I hit this too, when I was starting, and I think the error message is unclear. The compiler knows the parameter is a function, and it looks like we're trying to pass a method into that function. It should say something like "Methods cannot be passed as functions, specify the type's function explicitly" (or something along those lines). It's a lot less likely this bug is due to you forgetting the parentheses for a method that returns a function... and even if that was the bug, it would be obvious when you look at that line. However, the method/function thing is much less obvious to anyone who either hasn't dealt with functions as objects, or to someone coming from a language where you can pass methods this way.

Jan Mercl

unread,
Mar 5, 2013, 8:19:01 AM3/5/13
to Nate Finch, golang-nuts
On Tue, Mar 5, 2013 at 1:57 PM, Nate Finch <nate....@gmail.com> wrote:
> I hit this too, when I was starting, and I think the error message is
> unclear. The compiler knows the parameter is a function, and it looks like
> we're trying to pass a method into that function. It should say something
> like "Methods cannot be passed as functions, specify the type's function
> explicitly" (or something along those lines).

if U cannot be assigned to T then the correct message is "Cannot
assign U to T". There is an unbound number of such U's and T's so
treating one particular pair specially is opening a can of worms.

-j

Nate Finch

unread,
Mar 5, 2013, 8:55:30 AM3/5/13
to golan...@googlegroups.com
On Tuesday, March 5, 2013 8:19:01 AM UTC-5, Jan Mercl wrote:

if U cannot be assigned to T then the correct message is "Cannot 
assign U to T". There is an unbound number of such U's and T's so 
treating one particular pair specially is opening a can of worms. 
 
Yes, that's true, and I'd be happy if it said something like that.  For example, if it said:

"cannot use t.Time (Method) as type func() in function argument" 

But it doesn't. It says:

"method t.Year is not an expression, must be called"

There's two possible reasons for someone writing t.Year: 

  1. It's a simple syntax error (forgetting the parentheses) which is relatively unlikely and pretty obvious when looking at the code
  2. They're trying to pass the method as a function (a not uncommon newbie error), which is a significantly more complex error to understand.

The compiler currently assumes the reason is the first one, and complains about that.... but it is by far the easier error to see and fix... evidenced by the fact that you don't see long threads about how to fix missing parentheses in function calls.

Any error message for case #1 that mentions t.Year at all would be enough to tell but the most neophyte coder how to fix the code, if all they were missing was the parentheses. 

So, if you have to pick one message to show, why not the one that works relatively well for #1, and is not completely useless for #2?

Nate Finch

unread,
Mar 5, 2013, 8:58:33 AM3/5/13
to golan...@googlegroups.com
Note, example of when you are simply forgetting the parentheses:

func Foo(i int) {}

Foo(t.Year)

error:  "Cannot use t.Time (method) as type int in function argument"

Still perfectly clear what the problem is. 

minux

unread,
Mar 5, 2013, 9:05:40 AM3/5/13
to golan...@googlegroups.com
the original problem (allowing method currying), is https://code.google.com/p/go/issues/detail?id=2280

As Go 1.1 already changed the representation of func, fix that issue is not that hard (certainly not XL).

Kevin Gillette

unread,
Mar 5, 2013, 1:30:10 PM3/5/13
to golan...@googlegroups.com
Does this mean that memory pages dynamically allocated to Go will now be marked non-executable on platforms that support it?

minux

unread,
Mar 5, 2013, 1:41:03 PM3/5/13
to Kevin Gillette, golan...@googlegroups.com
On Wed, Mar 6, 2013 at 2:30 AM, Kevin Gillette
<extempor...@gmail.com> wrote:
> Does this mean that memory pages dynamically allocated to Go will now be
> marked non-executable on platforms that support it?
Yes. Go 1.1 on all Unix platforms will use non-executable heap and stack.
Windows still needs some callback trampoline that must be allocated.
Reply all
Reply to author
Forward
0 new messages