2

In Lua, I can define a member function like this:

Foo = {}

function Foo:bar()
  ...
end

I realise this is just syntactic sugar for this:

Foo = {}

foo.bar = function(self)
  ...
end

Is there a way to write an anonymous function with an implicit self parameter or do I always have to spell out the self parameter on anonymous functions?

The motivation is to create coroutine member functions in a way most analogous to ordinary functions. I can do this:

Foo.bar = coroutine.wrap(function(self) ... end)

Or this:

function Foo:bar() ... end

Foo.bar = coroutine.wrap(Foo.bar)

But is there a way to do a one-line declaration with an implicit self parameter?

1 Answer 1

2

Short answer: not possible.


Longer:

As you've correctly identified, the syntactic sugar

exp ::= functiondef

functiondef ::= function funcbody
funcbody ::= ‘(’ [parlist] ‘)’ block end

stat ::= function funcname funcbody
stat ::= local function Name funcbody
funcname ::= Name {‘.’ Name} [‘:’ Name]

that enables the shorthand function name () end syntax (and thus the form with an implicit self variable) changes the function definition from an expression to a statement by introducing the assignment.

There is no mechanism to interrupt this syntactically, in order to insert an arbitrary expression in to the assignment (desired here: a functioncall, coroutine.wrap).

Similarly, the arguments to a function call must be expressions - so something like coroutine.wrap(function Foo:bar() end) is also not possible.

Short of modifying the language with a new keyword (think async function Foo:bar() end), your example of

Foo.bar = coroutine.wrap(function(self) ... end)

is as good as it gets. For what it is worth, this example is perfectly understandable, and self-documenting (IMO; pun intended).


Lua 5.4: 3 – The Language | 3.3.3 – Assignment | 3.4.10 – Function Calls | 3.4.11 – Function Definitions | 9 – The Complete Syntax of Lua

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer. I assume that also means there's no direct language support for constructing a partially-bound method with a self reference? Like using local x = foo:bar; x(). Obviously not useful like that, but useful to pass a member function as a callback etc. Of course you can always construct a free function that does the job, capturing self in the closure.
Correct again, as the functioncall self-insert is also purely syntactic sugar (foo:bar() -> foo.bar(foo), where foo is only evaluated once). Utilizing closures is definitely the approach for a bound function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.