Help Me 'Coin a Name' for this...

Hi again.  It’s a morning of odd topics for me.  In this post, I’m looking for community input on an idea I’m having trouble with.

I am writing a small tutorial on ‘best practices’ and in this writing I’ve become stuck describing a feature of Corona that I use regularly.

In Corona, a number of functions take a function reference OR an object reference, as long as that objects has a specially named field, referencing an appropriate function.

For example, you can write this:

local obj = display.newCircle( 240, 160, 30 ) timer.performWithDelay( 500, function() print( "x:" .. obj.x, "y:" .. obj.y) end, -1 )

, or you can write this:

local obj = display.newCircle( 240, 160, 30 ) obj.timer = function( self, event ) print( "x:" .. self.x, "y:" .. self.y ) timer.performWithDelay( 500, obj ) end timer.performWithDelay( 500, obj )

, which is better.  Of course, this is the best (safest):

local obj = display.newCircle( 240, 160, 30 ) -- Safely stops when display object has been deleted obj.timer = function( self, event ) if( self.removeSelf == nil ) then return end print( "x:" .. tostring(self.x), "y:" .. tostring(self.y), "@" .. tostring(event.time) .. " ms" ) print("-------------\n") timer.performWithDelay( 500, self ) end timer.performWithDelay( 500, obj ) -- Delete obj in 1.75 seconds to show this is safe timer.performWithDelay( 1750, function() display.remove( obj ) end )

Closure Fields

Before we get distracted by what I did above, let me draw you back to the topic.  The question at hand is, “What should I call that field?”  i.e. ‘obj.timer

There are lots of these:

  • obj.timer - As shown, used for timers.
  • obj.touch - For touches.
  • obj.tap - For taps.
  • obj.onComplete - For transition.to( obj, { onComplete = obj } ) 
  • … etc.

Some of these are used for ‘listeners’ others are used for closures (as in the case of ‘timer’).  Because, you can consider some coding cases for listeners to be a sub-set of closures, I’m thinking that calling these ’ closure fields’ makes the most sense.

Please, give me  your input if you have any ideas on this.  Also, if there already exists a name for this and I was so silly as to miss it, please let me know.

Kudos and thanks to all who particpate!

Oh, and you can see more examples of ‘closure fields’ HERE.

Interesting question Ed.
I have been referring to these situations simply as properties in my books (i.e., anything with a period (.) is a a property, anything with a colon ( : ) is a method), but I see the need to distinguish these special properties (or fields) since they can contain a closure.

I like the term ’ c** losure fields ’ or ’ closure properties**’ and will support the use of the term.

BTW, thanks for the great ‘safe’ example of using a closure!

Wow! That’s a tough one, especially since we’re talking about a function that is referenced like a property. Would " closure reference"  make sense? ‘Closure property’ is a mathematical term, according to Google, so that might be confusing in some contexts.

I simply call it “that thing I still struggle getting the hang of”… :slight_smile: Thanks Ed for making this topic a little easier to grasp and all your other wonderful tutorials.

Howdy,

Interesting question. I’m pretty sure that is a property, like Dr. B said.  I would be careful to overcomplicate it.  In my opinion it’s a property, and like other properties can take different types of values.  In this case sometimes it’s a function, others an object.

My 2 pence.

Cheers.

It’s really just a calling convention of the EventListener object (and descendents), and since Corona calls them “listeners” I’d just continue that usage to avoid confusion:

tables-that-follow-their-listener-convention = “table listeners”

functions-that-follow-their-listener-convention = “function listeners”

I have to agree with Dr. B.   if it’s not a function i.e., you reference it  obj.value   – its an attribute or property.  Attribute is more of the OOP flavor for it.   If you reference it with () at the end (since Lua lets you do both : and .), then it’s a method in the OOP world.  If you check the type of the variable it will say “function”, then you can get a way with the normal terms like method, function etc. to refer to them.  You could if you need to say:

anonymous function reference.

Rob

Not that you should take this as gospel, but this has been described in the Corona docs since time immemorial (where “time immemorial” is roughly equivalent to early 2010) as a “table listener”, which makes sense since ‘obj’ in your sample code is a table. By contrast, the first bit of sample code is described as a “function listener”.

You can see this described in the Corona docs - using, as it happens, timer.performWithDelay.

This seems straightforward enough. I don’t believe that this second example you give - what the docs call a table listener - would actually meet the typical criteria of a closure. What you have there is just a plain old function (which of course is perfectly fine! It’s just not a closure).

(Edit: Sorry, in reading your post more closely, I realized that the above isn’t quite answering your actual question: what to call the .timer reference. I’d simply call it a field that stores a reference to a function. Since functions are first-class objects in Lua, they get the same treatment as any other object. Since the function isn’t necessarily a closure, I’d avoid using that term to describe the general case. According to the Lua Reference Manual, methods are functions that use colon syntax, which isn’t technically required when using table listeners.)

Darren

Also, this would, I think, be a decent example of using closures in combination with table listeners, since the callback() function that is returned by getTimerFunction() keeps the specific value of xIncrement passed to it in its scope:

local obj1 = display.newCircle(40, 160, 10) local obj2 = display.newCircle(40, 260, 10) local function getTimerFunction(xIncrement) local function callback(self, event) if not self.removeSelf then return end self.x = self.x + xIncrement end return callback end obj1.timer = getTimerFunction(5) obj2.timer = getTimerFunction(10) timer.performWithDelay(1000, obj1, 0) timer.performWithDelay(1000, obj2, 0)

(Sorry about the sub-optimal code formatting; it’s been a while since I posted to the forums.)

Darren

In Javascript, these are called expando properties.

That’s the generic term for adding arbitrary things to an existing object anyway. Not specifically functions.

Interesting question Ed.
I have been referring to these situations simply as properties in my books (i.e., anything with a period (.) is a a property, anything with a colon ( : ) is a method), but I see the need to distinguish these special properties (or fields) since they can contain a closure.

I like the term ’ c** losure fields ’ or ’ closure properties**’ and will support the use of the term.

BTW, thanks for the great ‘safe’ example of using a closure!

Wow! That’s a tough one, especially since we’re talking about a function that is referenced like a property. Would " closure reference"  make sense? ‘Closure property’ is a mathematical term, according to Google, so that might be confusing in some contexts.

I simply call it “that thing I still struggle getting the hang of”… :slight_smile: Thanks Ed for making this topic a little easier to grasp and all your other wonderful tutorials.

Howdy,

Interesting question. I’m pretty sure that is a property, like Dr. B said.  I would be careful to overcomplicate it.  In my opinion it’s a property, and like other properties can take different types of values.  In this case sometimes it’s a function, others an object.

My 2 pence.

Cheers.

It’s really just a calling convention of the EventListener object (and descendents), and since Corona calls them “listeners” I’d just continue that usage to avoid confusion:

tables-that-follow-their-listener-convention = “table listeners”

functions-that-follow-their-listener-convention = “function listeners”

I have to agree with Dr. B.   if it’s not a function i.e., you reference it  obj.value   – its an attribute or property.  Attribute is more of the OOP flavor for it.   If you reference it with () at the end (since Lua lets you do both : and .), then it’s a method in the OOP world.  If you check the type of the variable it will say “function”, then you can get a way with the normal terms like method, function etc. to refer to them.  You could if you need to say:

anonymous function reference.

Rob

Not that you should take this as gospel, but this has been described in the Corona docs since time immemorial (where “time immemorial” is roughly equivalent to early 2010) as a “table listener”, which makes sense since ‘obj’ in your sample code is a table. By contrast, the first bit of sample code is described as a “function listener”.

You can see this described in the Corona docs - using, as it happens, timer.performWithDelay.

This seems straightforward enough. I don’t believe that this second example you give - what the docs call a table listener - would actually meet the typical criteria of a closure. What you have there is just a plain old function (which of course is perfectly fine! It’s just not a closure).

(Edit: Sorry, in reading your post more closely, I realized that the above isn’t quite answering your actual question: what to call the .timer reference. I’d simply call it a field that stores a reference to a function. Since functions are first-class objects in Lua, they get the same treatment as any other object. Since the function isn’t necessarily a closure, I’d avoid using that term to describe the general case. According to the Lua Reference Manual, methods are functions that use colon syntax, which isn’t technically required when using table listeners.)

Darren

Also, this would, I think, be a decent example of using closures in combination with table listeners, since the callback() function that is returned by getTimerFunction() keeps the specific value of xIncrement passed to it in its scope:

local obj1 = display.newCircle(40, 160, 10) local obj2 = display.newCircle(40, 260, 10) local function getTimerFunction(xIncrement) local function callback(self, event) if not self.removeSelf then return end self.x = self.x + xIncrement end return callback end obj1.timer = getTimerFunction(5) obj2.timer = getTimerFunction(10) timer.performWithDelay(1000, obj1, 0) timer.performWithDelay(1000, obj2, 0)

(Sorry about the sub-optimal code formatting; it’s been a while since I posted to the forums.)

Darren

In Javascript, these are called expando properties.

That’s the generic term for adding arbitrary things to an existing object anyway. Not specifically functions.