Card Game

General discussion about LÖVE, Lua, game development, puns, and unicorns.
tdc5013
Prole
Posts: 38
Joined: Wed Feb 08, 2012 4:24 pm

Re: Card Game

Post by tdc5013 »

Ok. I get that :)

So if ipairs basically does the same job as a basic for loop, why does it exist? Is there a specific function it can apply to, where you'd need to specifically use it, rather than something like the for loop you illustrated?
User avatar
MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

Re: Card Game

Post by MarekkPie »

I don't see any practical difference; the only thing I can think is perhaps there is a speed difference between regular for and ipairs. I know there is a difference between ipairs and pairs (with pairs being faster), but I am not certain about regular for and ipairs.

Maybe its like how Python programmers say do it the "Python way." ipairs is the Lua way.
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Card Game

Post by Nixola »

Kikito, in his tile tutorial, says that the regular for is faster
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Card Game

Post by bartbes »

I haven't got the statistics, but yes, it is. ipairs is more idiomatic however, and in general people don't really care about those tiny speed-ups (and you shouldn't, either). There is, however, a difference, ipairs doesn't have to go to #t (with t being the table), since that can include embedded nils.
Example:

Code: Select all

print(#{1, nil, 2}) --> 3
local counter = 0
for i, v in ipairs{1, nil, 2} do
   counter = counter + 1
end
print(counter) --> 1
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Card Game

Post by kikito »

ipairs, for a while, was going to be removed from Lua 5.2 . Or there were rumors about it; I didn't pay too much attention to them. At the end, it was kept in Lua, and I think that was a good decision.
tdc5013 wrote:So if ipairs basically does the same job as a basic for loop, why does it exist? Is there a specific function it can apply to, where you'd need to specifically use it, rather than something like the for loop you illustrated?
That's a very good question. I thought about it myself, and found a possible explanation.

First of all, ipairs is not exactly like pairs. pairs doesn't give any guarantee about the order in which the elements of the array are parsed. I think right now, it *does* respect the numerical order, but that's an implementation detail; other implementations, like LuaJIT or Lua 5.3, could change the implementation so that it didn't respect the order, and that would still be compatible with the Lua spec. My point is, you can't make the assumption in your code when using pairs.

The obvious conclusion to all this is - ok, I'll use a numeric for then. So, why do I need ipairs?

Well, the answer is, yeah, use a numeric for when you can. But in some occasions you can't. Sometimes you just need an iterator function.

Consider the typical copy function:

Code: Select all

function copy(tbl)
  local result = {}
  for k,v in pairs(tbl) result[k] = v end
  return result
end
As far as I know, in the standard 5.1 Lua, this function works with both hash-like tables and array-like tables - but this is an implementation detail; pairs is not guaranteed to follow the numerical order in keys, so in the next version of Lua, or in an alternative implementation, it might copy the keys in a different order (so it would not generate an array, but a hash). Without ipairs, you would end up needing two different implementations; one for copying arrays, using the numeric for, which is guaranteed to follow the numeric keys, and another one for the rest.

But with ipairs, you can do this:

Code: Select all

function copy(tbl, iterator)
  iterator = iterator or pairs
  local result = {}
  for k,v in iterator(tbl) result[k] = v end
  return result
end
This version of the function accepts a second (optional) parameter called "iterator". By default, it is pairs. But you can set it to ipairs if you want:

Code: Select all

t1 = {1,2,3}
t2 = copy(t1, ipairs)
So, you can get numerical order, if you need it.

Setting the iterator as an optional parameter has another benefit: you can example, create an iterator function that returns only the even members of the array - or the members of the array in reverse order. Or only the members of a hash whose key starts with "a". And the copy function will work with those, too:

Code: Select all

t3 = copy(t1, evenpairs)
t4 = copy(t1, reverseipairs)
t5 = copy(t1, keystartpairs("a"))
So, this is the reason I imagine ipairs exist: When you are developing a function that parses tables, sometimes,you want to let the users of that function specify how they want to parse a table - like with the iterator parameter. And on the other hand, when you are using that function, you may want to have the guarantee that the numeric values are parsed in order. Granted - very rare case. But possible.

At least that is my opinion. I haven't checked that on the Lua mailing list or anything.
Last edited by kikito on Sun Feb 12, 2012 11:26 am, edited 1 time in total.
When I write def I mean function.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Card Game

Post by Robin »

What I like about ipairs is that it reduces the "housekeeping" you have to do. Compare:

Code: Select all

for i = 1, #t do
    --.... use i and t[i] here
end
and:

Code: Select all

for i = 1, #t do
    local v = t[i]
    --.... use i and v here
end
to:

Code: Select all

for i, v in ipairs(t) do
    --.... use i and v here
end
In the last, you don't have to index your table or declare an extra local variable all the time, which could distract from the algorithm inside the loop.
Help us help you: attach a .love.
tdc5013
Prole
Posts: 38
Joined: Wed Feb 08, 2012 4:24 pm

Re: Card Game

Post by tdc5013 »

Thanks, I understand this now, I think. Slightly different ways of implementation, but if i needed ipairs has a few more functions that For doesn't (even though it's possible to program them with a For loop, it would require a few more lines of code).
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 5 guests