Lua coroutine.yield(-1)'s meaning? - lua

What does coroutine.yield(-1) mean? I don't understand -1 here.
code piece and out put is:
> function odd(x)
>> print('A: odd', x)
>> coroutine.yield(x)
>> print('B: odd', x)
>> end
>
> function even(x)
>> print('C: even', x)
>> if x==2 then return x end
>> print('D: even ', x)
>> end
>
> co = coroutine.create(
>> function (x)
>> for i=1,x do
>> if i==3 then coroutine.yield(-1) end
>> if i % 2 == 0 then even(i) else odd(i) end
>> end
>> end)
>
> count = 1
> while coroutine.status(co) ~= 'dead' do
>> print('----', count) ; count = count+1
>> errorfree, value = coroutine.resume(co, 5)
>> print('E: errorfree, value, status', errorfree, value, coroutine.status(co))
>> end
---- 1
A: odd 1
E: errorfree, value, status true 1 suspended
---- 2
B: odd 1
C: even 2
E: errorfree, value, status true -1 suspended
---- 3
A: odd 3
E: errorfree, value, status true 3 suspended
---- 4
B: odd 3
C: even 4
D: even 4
A: odd 5
E: errorfree, value, status true 5 suspended
---- 5
B: odd 5
E: errorfree, value, status true nil dead
>

Any arguments passed to the corresponding coroutine.yield are returned by coroutine.resume. So -1 in coroutine.yield(-1) here is nothing special, it's similar to coroutine.yield(x) in the function odd(x).
It is executed when counter is 2 and i is 3. The corresponding output is:
---- 2
B: odd 1
C: even 2
E: errorfree, value, status true -1 suspended
After ture which indicates no error, see the -1 here? That's the value from the call to coroutine.yield(-1), it ended up as a return value of coroutine.resume.
For the similar reason, the other return values of coroutine.resume are 1, 3 and 5, all coming from coroutine.yield(x) in the function odd(x).

coroutine.yield (ยทยทยท)
Suspends the execution of the calling coroutine. The coroutine cannot be running a C function, a metamethod, or an iterator. Any arguments to yield are passed as extra results to resume.
http://www.lua.org/manual/5.1/manual.html#pdf-coroutine.yield
So in other words the -1 could have been anything or even multiple values and how those values are used is up to the programmer.

Related

How to implement combinations tail-recursively?

I'm teaching myself Lua by reading Ierusalimschy's Programming in Lua (4th edition), and doing the exercises. Exercise 6.5 is
Write a function that takes an array and prints all combinations of the elements in the array.
After this succinct statement the book gives a hint that makes it clear that what one is expected to do is to write a function that prints all the C(n, m) combinations of m elements from an array of n elements.
I implemented the combinations function shown below:
function combinations (array, m)
local append = function (array, item)
local copy = {table.unpack(array)}
copy[#copy + 1] = item
return copy
end
local _combinations
_combinations = function (array, m, prefix)
local n = #array
if n < m then
return
elseif m == 0 then
print(table.unpack(prefix))
return
else
local deleted = {table.unpack(array, 2, #array)}
_combinations(deleted, m - 1, append(prefix, array[1]))
_combinations(deleted, m, prefix)
end
end
_combinations(array, m, {})
end
It works OK, but it is not tail-recursive.
Can someone show me a tail-recursive function that does the same thing as combinations above does?
(For what it's worth, I am using Lua 5.3.)
NB: I realize that the exercise does not require that the function be tail-recursive. This is a requirement I have added myself, out of curiosity.
EDIT: I simplified the function slightly, but removing a couple of nested functions that were not adding much.
There is a third option, one that doesn't have a snake eating it's tail. Although recursion with tail-calls don't lead to stack overflow, I avoid doing so out of personal preference. I use a while loop and a stack that holds the information for each iteration. Within the loop you pop the next task from the stack, do the work, then push next task onto the stack. I feel it looks cleaner and it's easier to visualize the nesting.
Here is how I would translate your code into the way I would write it:
function combinations(sequence, item)
local function append(array, item)
local copy = {table.unpack(array)}
copy[#copy + 1] = item
return copy
end
local stack = {}
local node = { sequence, item, {} }
while true do
local seq = node[ 1 ]
local itm = node[ 2 ]
local pre = node[ 3 ]
local n = #seq
if itm == 0 then
print(table.unpack(pre))
elseif n < itm then
-- do nothing
else
local reserve = {table.unpack(seq, 2, #seq)}
table.insert(stack, { reserve, itm, pre })
table.insert(stack, { reserve, itm-1, append(pre, seq[ 1 ]) })
end
if #stack > 0 then
node = stack[ #stack ] -- LIFO
stack[ #stack ] = nil
else
break
end
end
end
You can use this while-loop stack/node technique for just about any recursive method. Here is an example where it's applied to printing deeply nested tables: https://stackoverflow.com/a/42062321/5113346
My version, using your input example gives the same output:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5.
Forgive me if it doesn't work with other passed params because I didn't try to solve the answer to the exercise but rather just rewrite the code in your original post.
OK, I think I found one way to do this:
function combinations (array, m)
local dropfirst = function (array)
return {table.unpack(array, 2, #array)}
end
local append = function (array, item)
local copy = {table.unpack(array)}
copy[#copy + 1] = item
return copy
end
local _combinations
_combinations = function (sequence, m, prefix, queue)
local n = #sequence
local newqueue
if n >= m then
if m == 0 then
print(table.unpack(prefix))
else
local deleted = dropfirst(sequence)
if n > m then
newqueue = append(queue, {deleted, m, prefix})
else
newqueue = queue
end
return _combinations(deleted, m - 1,
append(prefix, sequence[1]),
newqueue)
end
end
if #queue > 0 then
newqueue = dropfirst(queue)
local newargs = append(queue[1], newqueue)
return _combinations(table.unpack(newargs))
end
end
_combinations(sequence, m, {}, {})
end
This version is, I think, tail-recursive. Unfortunately, it does not print out the results in as nice an order as did my original non-tail-recursive version (not to mention the added complexity of the code), but one can't have everything!
EDIT: Well, no, one can have everything! The version below is tail-recursive, and prints its results in the same order as does the original non-tail-recursive version:
function combinations (sequence, m, prefix, stack)
prefix, stack = prefix or {}, stack or {}
local n = #sequence
if n < m then return end
local newargs, newstack
if m == 0 then
print(table.unpack(prefix))
if #stack == 0 then return end
newstack = droplast(stack)
newargs = append(stack[#stack], newstack)
else
local deleted = dropfirst(sequence)
if n > m then
newstack = append(stack, {deleted, m, prefix})
else
newstack = stack
end
local newprefix = append(prefix, sequence[1])
newargs = {deleted, m - 1, newprefix, newstack}
end
return combinations(table.unpack(newargs)) -- tail call
end
It uses the following auxiliary functions:
function append (sequence, item)
local copy = {table.unpack(sequence)}
copy[#copy + 1] = item
return copy
end
function dropfirst (sequence)
return {table.unpack(sequence, 2, #sequence)}
end
function droplast (sequence)
return {table.unpack(sequence, 1, #sequence - 1)}
end
Example:
> combinations({1, 2, 3, 4, 5}, 3)
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
Ironically, this version achieves tail-recursion by implementing its own stack, so I am not sure it is ultimately any better than the non-tail-recursive version... Then again, I guess the function's stack actually lives in the heap (right?), because Lua's tables are passed around by reference (right?), so maybe this is an improvement, after all. (Please correct me if I'm wrong!)

Why does ZeroBrane studio evaluates "^" as not a number when the power is a double

Well as it generally says, I have the following situation. I wrote a "main.lua" file, which includes the other file with an object definition having the following method:
function self:Process(vRef,vOut,bNeg)
mErrO = mErrN
mErrN = (bNeg and (vOut-vRef) or (vRef-vOut)) -- Refresh error state
logStatus(nil,"MER= "..mErrO.." > "..mErrN)
local errS = getSign(mErrN)
-- P-Term
logStatus(nil,"S P: >> "..tostring(errS))
local errP = mErrN; logStatus(nil,"0 P: >> "..tostring(errP))
errP = errP^mpP; logStatus(nil,"1 P: >> "..tostring(errP))
errP = math.abs(errP); logStatus(nil,"2 P: >> "..tostring(errP))
errP = errP*errS; logStatus(nil,"3 P: >> "..tostring(errP))
As you all may see, if we have like (-198^1.01), the result must be ( respectively ) (-208.75257542111). I added the following line in the "main.lua" file:
local a = (-198^1.01)
local b = ( 198^1.01)
local c = ( 0^1.01)
logStatus(nil,"-------------Pow: {"..a..","..b..","..c.."}")
However, these are calculated correctly. I thin it is somehow related by the object and the fact that the ZeroBrane must be using an older version of Lua. Strangely when the power argument is 1,2,3,4 ... It works fine. The program output is as follows:
-------------Pow: {-208.75257542111,208.75257542111,0}
MER= 0 > -198
S P: >> -1
0 P: >> -198
1 P: >> nan
2 P: >> nan
3 P: >> nan
Any answer will be appreciated !
In your first code
local errP = mErrN; --> -198
errP = errP^mpP; --> nan
the expression being calculated is (-198)^1.01.
It is nan according to math definition of raising to power and according to the man page of pow():
pow(x, y) returns a NaN and raises the "invalid" floating-point exception for finite x < 0 and finite non-integer y.
In your second code
local a = (-198^1.01)
the expression is -(198^1.01) according to Lua operators precedence.
This expression equals to -208.75...
Probably you would want to calculate math.abs(x)^y * (x<0 and -1 or 1) instead of x^y

F# Function where x is divisible by 2 or 3 but not 5

I have a function that determines whether a value is divisible by 2 or 3, but **NOT** 5:
let ttnf x =
if (x % 2 = 0) || (x % 3 = 0) && not(x % 5 = 0) then true
else
false
I'm getting a weird response from Visual Studio 2015 in the interactive panel.
I execute the above code in the F# interactive panel then enter say...
ttnf 15
Hit enter, nothing...
hit alt + enter then it returns it on the second time.
Any idea why it isn't returning true/false from entering:
ttnf 15
The first time?
Thanks.
#ildjarn commented about the error in your code, but about F# interactive's behavior: when you type code directly into fsi, you need to terminate each declaration with ;; to tell fsi to interpret it, otherwise it will just wait for you to continue your input (as you experienced). So:
> let ttnf x =
if (x % 2 = 0 || x % 3 = 0) && not(x % 5 = 0) then true
else
false;;
val ttnf : x:int -> bool
> ttnf 15;;
val it : bool = false
>

Explain why unpack() returns different results in Lua

The following script finds prime numbers in a range from 1 to 13.
When I explicitly iterate over the table that contains the results I can see that the script works as expected. However, if I use unpack() function on the table only the first 3 numbers get printed out.
From docs: unpack is "a special function with multiple returns. It receives an array and returns as results all elements from the array, starting from index 1".
Why is it not working in the script below?
t = {}
for i=1, 13 do t[i] = i end
primes = {}
for idx, n in ipairs(t) do
local isprime = true
for i=2, n-1 do
if n%i == 0 then
isprime = false
break
end
end
if isprime then
primes[idx] = n
end
end
print('loop printing:')
for i in pairs(primes) do
print(i)
end
print('unpack:')
print(unpack(primes))
Running
$ lua5.3 primes.lua
loop printing:
1
2
3
5
7
13
11
unpack:
1 2 3
Change
primes[idx] = n
to
primes[#primes+1] = n
The reason is that idx is not sequential as not every number is a prime.

lua - table maintenance (particle system related)

The update() function below gets called on every frame of a game. If the Drop particle has y value greater than 160 I want to remove it from the table. The problem is that I get "attempt to compare number with nil" errors, on the line notated below:
local particles = {};
function update()
local num = math.random(1,10);
if(num < 4) then
local drop = Drop.new()
table.insert ( particles, drop );
end
for i,val in ipairs(particles) do
if(val.y > 160) then --ERROR attempt to compare number with nil
val:removeSelf(); --removeSelf() is Corona function that removes the display object from the screen
val = nil;
end
end
end
What am I doing wrong? Obviously val is nil, but I don't understand why the table iteration would find val in the first place since I set it to nil when it's y value gets larger than 160.
Thanks for the answers, they were all helpful. Here is what ended up working for me. The table.remove call is necessary to keep the loop running properly.
for i = #particles, 1, -1 do
if particles[i].y > 160 then
local child = table.remove(particles, i)
if child ~= nil then
display.remove(child)
child = nil
end
end
end
You're looking in the wrong place, the problem isn't that val is nil, it's val.y that's nil. See this example:
> x=nil
> if x.y > 10 then print("test") end
stdin:1: attempt to index global 'x' (a nil value)
stack traceback:
stdin:1: in main chunk
[C]: ?
> x={y=nil}
> if x.y > 10 then print("test") end
stdin:1: attempt to compare number with nil
stack traceback:
stdin:1: in main chunk
[C]: ?
Also, when you set val to nil, that may not be doing anything (I believe val is a copy):
> t={"a", "b", "c", "d"}
> for i,val in ipairs(t) do print(i, val) end
1 a
2 b
3 c
4 d
> for i,val in ipairs(t) do if i==3 then print("delete", val); val=nil end end
delete c
> for i,val in ipairs(t) do print(i, val) end
1 a
2 b
3 c
4 d
Edit: to delete an element from a table, you want table.remove:
> t[3]=nil
> for i,val in ipairs(t) do print(i, val) end
1 a
2 b
> t[3]="c"
> for i,val in ipairs(t) do print(i, val) end
1 a
2 b
3 c
4 d
> for i,val in ipairs(t) do if i==3 then print("delete", val); table.remove(t, i) end end
delete c
> for i,val in ipairs(t) do print(i, val) end
1 a
2 b
3 d
JeffK's solution should work, but I think the reason it will work is not because of the fact that he's traversing the list backwards, but because he is setting particles[i] = nil instead of val = nil. If you run val = nil you're only setting the local copy of val to nil, not the entry in the table.
Try this:
for i,val in ipairs(particles) do
if(val.y > 160) then
particles[i]:removeSelf()
particles[i] = nil;
end
end
I don't think you are allowed to modify the contents of a table while ipairs is iterating through it. I vaguely remember reading that my hardcopy of the Lua 5.1 Reference Manual, but I can't seem to locate it now. When you set val to nil, it removes an element from the particles table.
You might try processing the table in reverse, since your function is doing a full sweep of the particles table, conditionally removing some items:
for x = #particles, 1, -1 do
if particles[x].y > 160 then
particles[x]:removeSelf()
particles[x] = nil
end
end

Resources