Lua functions and other language details - LUA Scripting - CHDK Forum  

Lua functions and other language details

  • 18 Replies
  • 4019 Views
*

Offline reyalp

  • ******
  • 11902
Lua functions and other language details
« on: 08 / April / 2013, 13:04:17 »
Advertisements
Continued from http://chdk.setepontos.com/index.php?topic=7938.msg99008#msg99008
Quote
Known bug: the function "restore" in fps.lua doesn't get called when the script is interrupted (according to http://chdk.wikia.com/wiki/Script_commands#restore it should, not sure what's wrong)
restore needs to be defined before the script is interrupted, above the while loop.
While I have no doubt that you are correct about this,  it seems strange.  As I understand it,  Lua compiles to an intermediate state (like the old p-code) before executing (hence the error message that pop up when you try to run a script with syntax mistakes).  Seems like it should be able to spot a restore() function and do something appropriate at that point?
Nope. Lua compiles the entire file, but it doesn't execute anything until you actually run it. In Lua terms, the entire file becomes an anonymous function, which is then executed when you actually run the script. Function definitions are an executable statement.
Quote
Seems like it should be able to spot a restore() function and do something appropriate at that point?
No. A function is just a value (the compiled representation of the function) and a function name is just a regular variable. The value is only assigned when the function definition is actually executed
Code: [Select]
function foo() ... end is just syntactic sugar for
Code: [Select]
foo = function() ... end
so when you do
Code: [Select]
while ... do
...
end
function restore()
end
interrupting in the while is just the same as trying to access a global variable called "restore" at that point in the while loop.

This will seem funny to C programmers, but in C you couldn't put executable code outside of a function where the "while" is. If in lua, you put your main code in a function and called it at the end of the script, the order of the definitions wouldn't matter.

See also http://www.lua.org/manual/5.1/manual.html#2.5.9

javascript programmers will find this more familiar, but Lua scoping rules are far saner since it is block level rather than doing crazy hoisting.
Don't forget what the H stands for.

Re: Lua functions and other language details
« Reply #1 on: 08 / April / 2013, 15:00:37 »
Thanks - great explanation that gives this old C programmer some more appreciation for the elegance of Lua!

However,  I do find it strange that given all that,   Lua would arbitrarily designate a specific function name for the code that gets called when the program halts.  Would it not be more "pure" to use a function to do that - sort of like registering a call-back?  Something like :

Code: [Select]
function shutdown_callback()
....
end

register_restore_routine( shutdown_callback )

But then I tried to google for  "Lua restore"  and got no relevent hits.   So I think that tells me that the whole restore() thing is a CHDK implementation detail and nothing to do with core Lua.  Do I have that right ?


Ported :   A1200    SD940   G10    Powershot N    G16

*

Offline lapser

  • *****
  • 1093
Re: Lua functions and other language details
« Reply #2 on: 08 / April / 2013, 15:27:16 »
However,  I do find it strange that given all that,   Lua would arbitrarily designate a specific function name for the code that gets called when the program halts.
This might make it more clear. It looks like Lua calls the CHDK C function, lua_run_restore(), and that function defines "restore" as the name of function it calls.

The key, as Phil explained, is that this is an executable statement that defines and sets the value of the global variable "restore":

function restore()
  --
end
Code: [Select]
// run the "restore" function at the end of a script
// Mimic uBasic logic, return 0 to trigger script interrupt immediately
int lua_run_restore()
{
lua_getglobal(Lt, "restore");
if (lua_isfunction(Lt, -1)) {
if (lua_pcall( Lt, 0, 0, 0 )) {
script_console_add_line( (long)lua_tostring( Lt, -1 ) );
}
        if (lua_script_is_ptp == 0)
            script_console_add_line(LANG_CONSOLE_TEXT_FINISHED);
}
    return 0;
}
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

*

Offline lapser

  • *****
  • 1093
Re: Lua functions and other language details
« Reply #3 on: 08 / April / 2013, 15:39:52 »
While we're at it, I'd like to understand the use of "local" variables a little better. I understand that their scope is within the block they're contained in. But shouldn't we be using local variables whenever possible?

And what's the meaning of a local variable defined at the beginning of the "main" block?  Is that permitted?

I read that local variables are accessed with an index address, while global variables use a hash table? Can you explain this? Would this mean that local variables take less memory and are accessed faster? Is the text name of a global variable stored, so longer names take more memory?

Yes, the more I learn about Lua, the better I like it. I'm using Lua for Windows for the editor, plus I can run the Lua program to check for syntax errors before loading it on the camera. I was thinking about writing a program in Lua to run on the computer, not the camera. How hard is it to create a complete file that runs a Lua program on Windows or Mac, i.e. would the Lua program be cross platform?
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos


*

Offline reyalp

  • ******
  • 11902
Re: Lua functions and other language details
« Reply #4 on: 08 / April / 2013, 15:57:56 »
So I think that tells me that the whole restore() thing is a CHDK implementation detail and nothing to do with core Lua.  Do I have that right ?
Exactly...  restore is not a lua thing, it's hack done in chdk, to match the ubasic "restore" label.

The closest thing Lua has pre-defined is garbage collection metamethods, but this isn't directly equivalent.
Don't forget what the H stands for.

*

Offline reyalp

  • ******
  • 11902
Re: Lua functions and other language details
« Reply #5 on: 08 / April / 2013, 16:27:32 »
While we're at it, I'd like to understand the use of "local" variables a little better. I understand that their scope is within the block they're contained in. But shouldn't we be using local variables whenever possible?

And what's the meaning of a local variable defined at the beginning of the "main" block?  Is that permitted?
There's nothing special about the "main" block, so yes, locals are fine at file scope. They are just local to that chunk.

Using locals everywhere is generally fine and can efficient, but there are some subtleties that can trip you up. If you use a local before it is defined, you will get the global instead.

You might expect something like
Code: [Select]
function foo()
return x+1
end
local x = 1
foo()
to be fine, but it will cause an error, because when foo() is created, it x is bound to the global named x. If X isn't local, it will return 2, because the value is assigned before foo is executed.

If you move local x = 1 to before foo, that will also work because x inside foo is bound to the local x.

The real power of using locals defined at a higher scope than the function is closures, but that's a topic for another post.
Quote
I read that local variables are accessed with an index address, while global variables use a hash table? Can you explain this? Would this mean that local variables take less memory and are accessed faster? Is the text name of a global variable stored, so longer names take more memory?
Globals are stored in a regular lua table, which by default is available as a global named _G. (and yes. _G._G = _G) They are somewhat less efficient than locals, but this likely doesn't matter in most cases. You can also create "environments" so different parts of the code have different global tables, see http://www.lua.org/manual/5.1/manual.html#2.9

The fun thing about globals being in a table is that you can attach metamethods to it just like any other table. One of the "warts" of lua is that undeclared globals are just a nil value, so if you mistype a variable name, it can go unnoticed. You can use metamethods to change this, so globals have to be declared to be used.

Quote
I was thinking about writing a program in Lua to run on the computer, not the camera. How hard is it to create a complete file that runs a Lua program on Windows or Mac, i.e. would the Lua program be cross platform?
If you use the standard command line interface to Lua (the "lua" command included with any standard lua distribution), then it should be very portable.

The lua library itself is also very portable, so if you embed it in an ANSI C program, it should run anywhere with an ANSI compiler and standard libraries.

I tend to use chdkptp as a place to run quick and dirty lua code, even when it's not directly related to the ptp part. (see extras/vxromlog.lua for an example)

the chdk tools directory also contains "hostlua" which is set up to allow you to build a version of lua more similar to what runs on CHDK.
Don't forget what the H stands for.

*

Offline lapser

  • *****
  • 1093
Re: Lua functions and other language details
« Reply #6 on: 08 / April / 2013, 18:27:43 »
Thanks for all the great info, reyalp.

So would a local variable defined in the main chunk be visible to all the functions defined in the main chunk? How about in libraries loaded by the main chunk?
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

*

Offline reyalp

  • ******
  • 11902
Re: Lua functions and other language details
« Reply #7 on: 08 / April / 2013, 23:28:05 »
So would a local variable defined in the main chunk be visible to all the functions defined in the main chunk?
All functions (or other blocks) defined *after* the variable. See also http://www.lua.org/manual/5.1/manual.html#2.6

Quote
How about in libraries loaded by the main chunk?
No. require(), dofile() etc are not the same as including the code of the module. They are ordinary functions, so they only have access to locals that were in scope when they were defined (lua startup in this case), not where they are called. When they in turn create a function from the loaded file, the same applies. (I almost got this one wrong, glad I checked :-[)

Globals from the main program may or may not be visible in a module, depending whether the module sets up it's own environment.

While we are on the topic of modules:

Lua 5.1 has a module() function (http://www.lua.org/manual/5.1/manual.html#5.3) which can be used to define a module. This is deprecated in 5.2.
edit: "module" and some other module related functions are disabled in the CHDK Lua implementation

The pattern I prefer for simple modules in chdk is shown in http://trac.assembla.com/chdk/browser/trunk/CHDK/LUALIB/capmode.lua

Rather than using module(), I just put everything in a locals. One local table contains all the public methods, and is returned at the end, which makes it the return value of require().

This means that the callers global namespace is not modified, the caller gets choose how the module is referred to:
Code: [Select]
bob=require'capmode'
bob.set'M'

Since the module is the return value, you can also just do
Code: [Select]
require'capmode'.set'M'

require() only loads the modules the first time you require(), so you don't have to worry that requiring the same module in multiple places will slow things down.

This is usually good, but if you are interactively testing something in a lua interpreter, require() won't reload it for you. In that case you can set packege.loaded['<name of the module'] to nil before requiring it again, or use dofile() or loadfile().
« Last Edit: 21 / April / 2013, 20:01:50 by reyalp »
Don't forget what the H stands for.


Re: Lua functions and other language details
« Reply #8 on: 08 / April / 2013, 23:43:04 »
Something tells me Lua is not going to end up in SDM any time soon.
Ported :   A1200    SD940   G10    Powershot N    G16

Re: Lua functions and other language details
« Reply #9 on: 09 / April / 2013, 08:04:22 »
Something tells me Lua is not going to end up in SDM any time soon.

It will NEVER be supported by SDM, why should it ?
We are just taking photos, not testing elegant programming techniques for the benefit of developers.
If a user really needs Lua (which is difficult to believe) just use CHDK.

In fact, I have suggested to someone that the new SDM installer should download SDM and CHDK, the CHDK DISKBOOT file having its extension temporarily changed.


 

Related Topics