Conventional function vs anonymous function

in Module TestCode:

M = {} function M:printFirstName(firstName) print(firstName) end M.printLastName = function(lastName) print(lastName) end return M

in main.lua you call the functions like so:

local mod = require("TestCode") mod:printFirstName("Robert") mod.printLastName("Paulson")

But it appears you can also interchange the “.” and “:” in some cases and not get an error, but the result is still broken code that may run.

I read a tutorial on this last night, but I don’t recall seeing “Use this way for x, y, z and here’s why” and “Use that way for a, b, c and here’s why”  but my take away (and I’m paraphrasing) “Do this here and do that there, if you want to, but any way will work”.

So other than preference, simplicity, expediency is there is great time to use anon or conventional function?

@Steve,

This:

M = {} function M:printFirstName(firstName) print(firstName) end return M

is the equivalent of this:

M = {} function M.printFirstName( self, firstName) print(firstName) end return M

The colon ( : ) is saying, “this function (a method) takes an implied reference to the calling object as the first argument and it will be named self”.

Likewise, when calling a function, if you use a colon ( : ), Lua interprets that to mean, pass a reference to the calling table/object as the first argument.  

So, in your original example, this would not work as you expected:

local mod = require("TestCode") mod:printLastName("Paulson")

It would print something, but not “Paulson”, because that call is equivalent to this:

local mod = require("TestCode") mod.printLastName( mod, "Paulson" )

As to why you would use one method over another.  There is no clear reason I can give you.  It is, IMHO a matter of convention and preference.
 
I mostly write my modules using dot (.) notation, because it rarely makes sense for my functions to be methods and I don’t need them to have a reference to the module.  i.e. They are each independent functions that don’t really care about the module or any of the other functions.
 
However, if I have a module, where the methods are going to cross call I might use colon (:slight_smile: notation.
 
Note.  Even when I know the object will be called using colon (:) notation, I typically specify using dot (.) notation:

local obj = display.newCircle( 10, 10, 10 ) function obj.touch( self, event ) ... body of touch here end obj:addEventListener( "touch" )

On a last note, if you’re thinking about private versus non-private construction of modules, Lua does not supply any concept of private.  So, the only one way (that I know) to achieve truly private functions in a module:

-- Forward Declarations of private functions (for visibility sake) local someFunction local aPrivateFunction local worker = {} -- Definition of module functions and merthods function worker.publicFunction( a, b ) return someFunction( a ) + aPrivateFunction(b) end function worker:publicMethod( a, b ) return self.publicFunction( a, b ) end -- Definition of private functions (I like to put them last and before the module return) someFunction = function( arg ) return 10 \* arg end aPrivateFunction = function( arg ) return arg/10 end return worker

If I can read my own code, this:

local worker = require "worker" --assumes I saved above in worker.lua worker:publicMethod(1,100)

Should print:   20

Are you sure that’s right RG?

mod:printLastName(“Paulson”) would still print Paulson, ‘self’ doesn’t over-write the first named parameter.

As long as the function was defined using m:printLastName, anyway. I run into to trouble when I freely interchange them for no reason and forget which convention I used for which function :smiley:

I am sure.  According to his first definition (first post)

M = {} M.printLastName = function(lastName) print(lastName) end return M

If you call it like this:

local mod = require("TestCode") mod:printLastName("Paulson")

It is the same as calling it like this:

local mod = require("TestCode") mod.printLastName( mod, "Paulson" )

In both cases, a reference to ‘mod’ will be passed as the first argument: lastName.  The string “Paulson” will be thrown away.

Remember, when you define  a function (I prefer term method) with a colon ( : ), you are implying the first argument will be a variable named self.  

When you call a function with a colon ( : ), you are explicitly passing a reference to the calling object as the first argument.  

On a side note.  This is why so often you see new folks post error messages about these functions:

  • table.insert() - Often wrongly called as table:insert()
  • obj:removeSelf() - Often wrongly called as obj.removeSelf()
  • and so on…

Well, yes - that’s why you wouldn’t call a " : " function using " . " and vice versa. Not intentionally anyway :slight_smile:

I think the confusion came from the fact that I wrote a modified version of his original code in my first answer.  I should have written a new module to answer the question, or I should have specified I was referring to the original code when I made my comment about dot versus colon.    :wacko:

Personally, I always use : to denote a function and . to denote a property on anything I code.  Keeps things simple and structured.  I find this helps when coding at 2 am.

To add more mud to the water.

If I’m building a module, I tend to define the functions with . instead of colon even if I’m expecting to use it with : to get a reference to the function:

local M ={} M.doSomething( self, firstRealParameter ) ...

This is very clear that the first thing that should be passed is a reference to myself.  Then I can either do:

myModule:doSomething(“Hello World”) 

or

myModule.doSoemthing(myModule, “Hello World”)

Rob

scope == privacy (or not), so module scope works, as does a closure environment:

function Person(name) return { getName = function(self) return name end } end local p = Person("Dave") print(p:getName()) --\> "Dave" print(p.name) --\> "nil"

Following X tutorial I see a convention used and I adopt it (as I’m new to Lua).

Then I need/want to see some related tutorial/video and the convention used is different (maybe not better or worse, just different), and it throws me off because then it creates doubt (which way is “right”, “correct”, “more accepted”, “best practices”).

So I am looking at a few function definition for Dusk at almost random:

function map.setCameraBounds(bounds) function map.setCameraFocus(f, noSnapCamera)

The above seem to be a hybrid of my first examples… more questions.  But I don’t think I’m doing anything particularly wrong.  functions = ‘:’ and properties = ‘.’ for now.

Your replies have been amazing and insightful.  Thank you all so much.  

As a C# developer, I like to think of the difference between . and : notation as the same as static and instance. This is because . functions won’t receive the ‘self’ and are more like free-standing methods or functions to be called on their own. Instance methods, on the other hand, have a notion of ‘self’ (‘this’ in C#) and are aware of the object of which they are a part. The definition in Lua is somewhat muddier, but it has it’s uses.

@Steve,

This:

M = {} function M:printFirstName(firstName) print(firstName) end return M

is the equivalent of this:

M = {} function M.printFirstName( self, firstName) print(firstName) end return M

The colon ( : ) is saying, “this function (a method) takes an implied reference to the calling object as the first argument and it will be named self”.

Likewise, when calling a function, if you use a colon ( : ), Lua interprets that to mean, pass a reference to the calling table/object as the first argument.  

So, in your original example, this would not work as you expected:

local mod = require("TestCode") mod:printLastName("Paulson")

It would print something, but not “Paulson”, because that call is equivalent to this:

local mod = require("TestCode") mod.printLastName( mod, "Paulson" )

As to why you would use one method over another.  There is no clear reason I can give you.  It is, IMHO a matter of convention and preference.
 
I mostly write my modules using dot (.) notation, because it rarely makes sense for my functions to be methods and I don’t need them to have a reference to the module.  i.e. They are each independent functions that don’t really care about the module or any of the other functions.
 
However, if I have a module, where the methods are going to cross call I might use colon (:slight_smile: notation.
 
Note.  Even when I know the object will be called using colon (:) notation, I typically specify using dot (.) notation:

local obj = display.newCircle( 10, 10, 10 ) function obj.touch( self, event ) ... body of touch here end obj:addEventListener( "touch" )

On a last note, if you’re thinking about private versus non-private construction of modules, Lua does not supply any concept of private.  So, the only one way (that I know) to achieve truly private functions in a module:

-- Forward Declarations of private functions (for visibility sake) local someFunction local aPrivateFunction local worker = {} -- Definition of module functions and merthods function worker.publicFunction( a, b ) return someFunction( a ) + aPrivateFunction(b) end function worker:publicMethod( a, b ) return self.publicFunction( a, b ) end -- Definition of private functions (I like to put them last and before the module return) someFunction = function( arg ) return 10 \* arg end aPrivateFunction = function( arg ) return arg/10 end return worker

If I can read my own code, this:

local worker = require "worker" --assumes I saved above in worker.lua worker:publicMethod(1,100)

Should print:   20

Are you sure that’s right RG?

mod:printLastName(“Paulson”) would still print Paulson, ‘self’ doesn’t over-write the first named parameter.

As long as the function was defined using m:printLastName, anyway. I run into to trouble when I freely interchange them for no reason and forget which convention I used for which function :smiley:

I am sure.  According to his first definition (first post)

M = {} M.printLastName = function(lastName) print(lastName) end return M

If you call it like this:

local mod = require("TestCode") mod:printLastName("Paulson")

It is the same as calling it like this:

local mod = require("TestCode") mod.printLastName( mod, "Paulson" )

In both cases, a reference to ‘mod’ will be passed as the first argument: lastName.  The string “Paulson” will be thrown away.

Remember, when you define  a function (I prefer term method) with a colon ( : ), you are implying the first argument will be a variable named self.  

When you call a function with a colon ( : ), you are explicitly passing a reference to the calling object as the first argument.  

On a side note.  This is why so often you see new folks post error messages about these functions:

  • table.insert() - Often wrongly called as table:insert()
  • obj:removeSelf() - Often wrongly called as obj.removeSelf()
  • and so on…

Well, yes - that’s why you wouldn’t call a " : " function using " . " and vice versa. Not intentionally anyway :slight_smile:

I think the confusion came from the fact that I wrote a modified version of his original code in my first answer.  I should have written a new module to answer the question, or I should have specified I was referring to the original code when I made my comment about dot versus colon.    :wacko:

Personally, I always use : to denote a function and . to denote a property on anything I code.  Keeps things simple and structured.  I find this helps when coding at 2 am.

To add more mud to the water.

If I’m building a module, I tend to define the functions with . instead of colon even if I’m expecting to use it with : to get a reference to the function:

local M ={} M.doSomething( self, firstRealParameter ) ...

This is very clear that the first thing that should be passed is a reference to myself.  Then I can either do:

myModule:doSomething(“Hello World”) 

or

myModule.doSoemthing(myModule, “Hello World”)

Rob