School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 307,095 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 2,002 people online right now. Registration is fast and FREE... Join Now!




Advanced Lua - Part II

 
Reply to this topicStart new topic

> Advanced Lua - Part II, Iterations, Iterations, Iterations...

KYA
Group Icon



post 25 Aug, 2009 - 05:13 PM
Post #1


Advanced Lua - Part II

Prerequisites:

A grasp on Lua along with programming fundamentals. While not necessary, reading Advanced Lua - Part I couldn't hurt.

Iterators:

An iterator is an object that allows a programmer to traverse through all the elements of a collection, regardless of its specific implementation. An example in C++:

cpp

#include <iostream>
#include <vector>
using namespace std;

int main() {
vector<int> theVector; //data structure
vector<int>::iterator theIter; //iterator

//fill it
for(int i = 0; i < 5; i++){
theVector.push_back(i+2);
}

//access using the iterator
for(theIter = theVector.begin(); theIter != theVector.end(); theIter++) {
cout << *theIter << endl;
}

return 0;
}


In this case, the programmer uses the iterator as a pre-defined object. It is specific to the data structure to be traversed (which we specify ahead of time) and comes as part of the STL. "Pre-defined" is important to note because (in this case) the programmer does NOT modify the object in any way, nor defines its default behavior (the writer(s) of this data structure did). Without going too far down a rat-hole, also know that a for loop (when using the index variable to access elements) is iteration as well, just a different form (sans object):

cpp

for(int i = 0; i < 5; i++){
cout << someArray[i]; //iteration
}


In Lua, the generic for loops come with a built in iterator. The for loop's syntax is as follows:

lua

for <var-list> in <exp-list> do
<body>
end


You've seen examples in previous tutorials, here are a few of the "built in" ones:

lua

--[[
Returns three values: the next function, the table t, and nil,
so that the construction

for k,v in pairs(t) do body end

will iterate over all key–value pairs of table t.
]]--
t = {5, 10, 15}
for k, v in pairs(t) do
print (k, v)
end

--[[
Returns three values: an iterator function, the table t, and 0,
so that the construction:

for i,v in ipairs(t) do body end

will iterate over the pairs (1,t[1]), (2,t[2]), •••,
up to the first integer key absent from the table.
]]--
names = {"Knowles", "Sally", "Bill"}
for i, v in ipairs(names) do
print(i, v)
end


You might be asking yourself why is this advanced? Most intros to [insert language here] include for loops. Yes, that's true, but the for loop itself is not what we're looking at. The focus is on the actual iteration, the objects involved, and the manner of execution. Knowing this information will allow you to take full advantage of Lua. Let's write out what Lua is calling/doing in the above for loops in another way to see exactly how they work:

lua

--[[

rewriting to show implementation

names = {"Knowles", "Sally", "Bill"}
for i, v in ipairs(names) do
print(i, v)
end

]]--

local function iter (a, i)
i = i + 1
local v = a[i]
if v then
return i, v
end
end

function ipairs(a)
return iter, a, 0
end

names = {"Knowles", "Sally", "Bill"}
for index, values in ipairs(names) do
print(values)
end

--[[

pairs() is essentially the same, but it calls the Lua function 'next'

rewriting to show implementation

t = {5, 10, 15}
for k, v in pairs(t) do
print (k, v)
end

]]--

function pairs(t)
return next, t, nil
end

names = {"Knowles", "Sally", "Bill"}
for index, values in pairs(names) do
print(values)
end


It is worth pointing out that these examples thus far are not true iterators. Meaning that the for loop does the actual iteration, the iterator only provides the successive values for the for loop. However, the concept is the same as in other programming languages (which call them iterators) so Lua kept the tradition. All of the above are "stateless" iterators. There are various ways to write complex state iterators (closures, tables, etc...), but they will not be covered in this tutorial.

The last two items cover how to write your own iterator. This example takes the concept of ipairs() and pairs() and modifies so it so that the return value is the value at the index rather then the index and value:

lua

--creating your own iterator
function values(t)
local i = 0
return function () --anon function, creates a closure
i = i + 1
return t[i]
end
end

--example usage
myArray = {10, 20, 30}
for item in values(myArray) do --using our created iterator (for each)
print(item) --continues until nil is returned
end


Instead of two variables in the var list, we now have one, which is the actual value at each index in the table. This still requires a for loop to dictate its function, so let's rewrite it as a stand alone entity that takes a parameter of a function (in this case print()) and uses a for loop internally:

lua

function values(t)
local i = 0
return function () --anon function, creates a closure
i = i + 1
return t[i]
end
end

--rewritten to be its own entity
function iter(func)
for item in values(myArray) do
func(item)
end
end

--usage
iter(print)


Nothing inherently changed in terms of functionality; we just moved it "inside" the iteration. Hopefully you found this both interesting and insightful. Happy coding!
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!


Fast ReplyReply to this topicStart new topic
2 User(s) are reading this topic (2 Guests and 0 Anonymous Users)
0 Members:

 


Lo-Fi Version Time is now: 11/21/09 11:41AM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month