Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Not The Basics — Gideros Forum

Not The Basics

tytadastytadas Member
edited October 2016 in General questions
Im sitting in the class, reading the PIL book or whatever you call it. And Im having an issue, understanding the Tail Calls, Iterators ans Closures. As I got the point, it's pretty important to understand it perfectly, but because words are pretty hard understandable, I'm asking here to help me out with this.

How did you get the meaning of Iterators, Taill Calls and Closures on your own?

(For all the haters who thinks i read it once - you're wrong)

Have a nice day!

Comments

  • ar2rsawseenar2rsawseen Maintainer
    Accepted Answer
    To simplify it

    Closures - variables that hold functions and can be called
    in lua it makes less sense, cause
    function a return 1 end --a is function
    local b = a --b is closure
    but in strictly types languages it makes more sense


    Tail Calls - last functions called in some scope (like outer function)
    function a return 1 end
    function b return 1 end
     
    function someFunction
        a() --function call
        b() --tail call
    end
    Iterators - function (or object that holds this function) that is called on each element in the array, list, map, (or any other object that holds many elements) like in a loop
    function iterate (t)
          --some internal variables like counters, etc
          local i = 0 
          local n = table.getn(t) 
          --the actual iterator function, which would loop through table and return value
          return function ()
               i = i + 1 --increase the internal count so we know which element to use
               return t[i] --return this element from table
          end
    end
    and we can use it in loops, like
    t = {10, 20, 30}
    for element in iterate(t) do
        print(element)
    end

    Likes: tytadas

    +1 -1 (+1 / -0 )Share on Facebook
  • piepie Member
    edited October 2016 Accepted Answer
    I think that you're starting too far; the PIL book seems a bit complex if you don't have a solid coding background.

    I suggest Arturs' book https://www.packtpub.com/game-development/gideros-mobile-game-development (available also on google books and maybe on amazon)
    It's very well written and explained, and guides you through the steps needed to develop a basic game.
    Once you've learned how things work in gideros, it's easy to understand what you need to do and when.

    About your question I think that you just need to know what iterators are, why should you care about tail calls and closures? :P
    Learn a few things at a time, you can always go deeper later.

    Simply put, iterators are functions that allow you to read (and eventually do something on each) entry of a table. ie. for, for... in pairs and for... in ipairs

    Another thing is: we're lucky there are no haters here.. :D

    [edit - Arturs was faster :) ]

    Likes: tytadas

    +1 -1 (+1 / -0 )Share on Facebook
  • Thank you! Yep, I'm going to buy the Arturs' book soon! But I have to do something before the book arrives :D
  • piepie Member
    buy it in epub or pdf and you won't have to wait - plus you will save some tree :D

    Likes: tytadas

    +1 -1 (+1 / -0 )Share on Facebook
  • Haha i'll have in mind :D
  • n1cken1cke Maintainer
    Accepted Answer
    There is mistake in this ar2rsawseen' example:
    function a return 1 end --a is function
    local b = a --b is closure
    Here variable `b` is simple function, not a closure! You just assign content of variable `a` to variable `b` i.e. reference to function in this case. In the end `a == b` and they do the same.
    Closure is a function with it's own table of upvalues. Upvalue is a local variable from enclosing function, neither a parameter of this function, nor global variable:
    -- NOTE: each file in Lua is compiled into function, so next function is still enclosed
    local counter = 0 -- this local variable is also an upvalue for the next function
    local function countUp() -- this function has no parameter `counter`
        counter = counter + 1 -- but it works because we created an upvalue
        return counter -- when we have used `counter` variable from enclosing function
    end
    Simply put, closure is a function+table i.e. function which has state and keeps it between calls. Closures are useful because you don't need to manually create those tables and you don't need to make them global, so you don't pollute global namespace because every function has it's own unique state and other functions has no way to modify it (except Lua `debug` library). And access to upvalues is much faster than to global variables.
    To better understand it: each function has access to: it's parameters (local variables from this function), it's upvalues (local variables from enclosing functions) and global variables.
    Just like classes, closures is another way to create and control objects but instead of class fields, methods and members they rely on functions, upvalues and lexical scoping. Most modern languages have it because in some cases they offer more clean and elegant approach than classes.

    Example from the PIL:
    -- Suppose you have a list of student names and a table
    -- that associates names to grades; you want to sort the list of names,
    -- according to their grades (higher grades first)
     
    names = {"Peter", "Paul", "Mary"}
    grades = {Mary = 10, Paul = 7, Peter = 8}
    table.sort(names, function (n1, n2)
          return grades[n1] > grades[n2]    -- compare the grades
    end)
    This works well when you only need to sort one table. Also note that grades is global variable here. What if you need to sort 3 tables or more?
    Without closures you need either create 3 versions of `function (n1, n2) return grades[n1] > grades[n2] end` (if you want to use different local variables for names and grades) or modify global variables `names` and `grades` each time before using it (easy to make a mistake).
    With closures we have clean solution:
    function sortbygrade (names, grades) 
        table.sort(names, function (n1, n2)
            return grades[n1] > grades[n2]    -- compare the grades
        end)
    end
    Here `grades` is also an upvalue for `return grades[n1] > grades[n2]` function because we didn't declare it as a parameter (and it's not a global variable) but enclosing function `sortbygrade` has it as local variable so we can freely use it to create a closure.

    Next example:
    function newCounter ()
    	local i = 0
    	return function ()   -- anonymous function
    		i = i + 1 -- `i` is upvalue because it's not declared in current function
    		return i -- and it's not a global variable
    	end
    end
     
    c1 = newCounter()
    print(c1())  --> 1
    print(c1())  --> 2
     
    c2 = newCounter()
    print(c2())  --> 1
    print(c2())  --> 2
    As you can see each closure has it's own unique upvalues. In this example we created two counters (c1 and c2) and both have it's own upvalues (`i` in this case).
    +1 -1 (+7 / -0 )Share on Facebook
  • @n1cke, Thank you for spending your precious time by explaining everything so clearly!! (*)
  • wow another goldmine lying here. Bookmarked this threat :-B
  • @talis "goldmine lying here"? What do you mean??
  • I mean the information shared here is like a gold in the goldmines. Waiting to be discovered and experimented.

    Likes: tytadas

    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.