Wednesday, February 28, 2007

New blog about programming

Because this blog is about scripting Anime Studio Pro, I thought it best to create a new blog that tries to capture what I'm doing to learn computer programming. Putting the posts in this blog wouldn't be fair for those who do not want to learn those other languages, and just concentrate on Lua and Anime Studio.

The new blog is called (no surprise there): I want to write programs.

Tuesday, February 27, 2007

Closure - 3

Wow, I finally got the concept of closure. I got it from reading Wikipedia - Scope (Programming)

Suppose you have this piece of code:

x = 0

do
  local x = 0
  function f () return x end
  function g () x = x + 1; return f() end
end

print(x)    -- 0
print(f() ) -- 0
print(g() ) -- 1
print(x)    -- 0

x = 5
print(x)    -- 5
print(f() ) -- 1
print(g() ) -- 2
print(x)    -- 5

The first occurrence of x is a global variable, which is dynamic; it can be changed by an assignment anywhere else in the program.

However, the second occurrence of x is something completely different. It is inside a do ... end construct (a chunk in Lua jargon), and it is defined local in that chunk. It cannot be accessed outside this chuck. Nevertheless, through the functions f and g the value of the x inside the do ... end construct can be accessed. It can be looked up in the script code, and, therefore, can be called a "lexical variable", because the scope of the variable is lexical (determined by executable code--functions--in the script). Remember, the functions f and g can be accessed outside the do ... end construct, because they are defined as global.

So a closure is a global function and its "lexical variables" (upvalues in Lua jargon), i.e. variables that can only be accessed through the function of the closure.

Now, suppose you had used a global variable x inside the do ... end construct:

x = 0

do
  x = 0
  function f () return x end
  function g () x = x + 1; return f() end
end

print(x)    -- 0
print(f() ) -- 0
print(g() ) -- 1
print(x)    -- 1

x = 5
print(x)    -- 5
print(f() ) -- 5
print(g() ) -- 6
print(x)    -- 6

Now there is only one and the same variable x, and there is no upvalue in this piece of code. Therefore, neither f nor g are closures.

Crash course programming

Well, I suppose like many of the readers of this blog, I never had a formal introduction into programming. Perhaps it is not so bad to take that step back, and do some programming basics.

The programming course using How to Design Programs and its programming environment DrScheme, is actually quite good. It start really simple with calculus, and progresses gently to more difficult topics. The programming environment is made more complex along with the increasing complexity of the course material. DrScheme has several language settings, which hide certain language constructs by making them invalid. In fact, this is a tailored teaching tool for anyone who wants to learn how to program, develop the skills and learn the discipline and methods how to solve problems.

If you haven't received a formal training in computer science, and you have no access to a classroom course, this is the next best thing for study. It isn't glamorous, but I think it is necessary to understand the basics of programming before attempting to write Lua scripts for Anime Studio.

Monday, February 26, 2007

How to Design Programs

Looking for free versions of the functional programming language Scheme, I found an excellent resource, called How to Design Programs. It is a book which uses the user-friendly DrScheme programming environment. Of course, I downloaded DrScheme, which is available for Windows 98+, Mac OS X 10.3+ and Unix type operating systems (Linux, BSD).

So why this diversion, why go to another language, and not continue with Programming in Lua? Well, I'm still having problems understanding the concepts of functional programming, especially the concept of closure. I've researched it in Wikipedia, and found that the answers in there still weren't satisfying my hunger for knowledge and understanding. I simply need to know what this concept of "closure" is.

I've seen that closure is used in lots of places (e.g. JavaScript, although it has some memory leakage in I.E. which needs to be addressed, see Leakfree JavaScript Closures), so it seems to be a pretty important concept.

Before I had read Chapter 6.1 of Programming in Lua, I wasn't really aware of the concept of functional programming, nor that a scripting language like Lua was capable enough to do some functional programming. You would think that a scripting language is downright imperative (do this, then that). Instead, it has some functional programming features, which makes it somewhat declarative (not so much "how to do it", but rather "what should be done").

Don't be afraid, this will not become a Scheme programming blog. I just need some extra baggage to be able to properly understand and explain the concepts I'm struggling with right now.

Sunday, February 25, 2007

Closure - 2

I'm beginning to understand what closure is. I cannot yet express it in words, but I can picture it in my mind. I've used Wikipedia as a reference, and it has some good articles on computer science (at least, the English language version at en.wikipedia.org).

Now, the text in Chapter 6.1 of Programming in Lua makes sense, while it did not before I studied the Wikipedia articles.

Friday, February 23, 2007

Closure

I've been doing the chapters of Programming in Lua, and I have arrived at chapter 6, "More about functions". Here the concept of closure is introduced and I'm having a hard time grasping the concept.

Here's an example:
-- sortbygrade.lua
names = {"Peter", "Paul", "Mary"}
grades = {Mary = 10, Paul = 7, Peter = 8}

print "-- unordered --"
for i,v in ipairs(names) do print(names[i], grades[v]) end
print "---------------"

table.sort(names, function (n1, n2)
    return grades[n1] > grades[n2]  -- compare the grades
end)

print "--- ordered ---"
for i,v in ipairs(names) do print(names[i], grades[v]) end
print "---------------"


-- function to do the same
function sortbygrade (names, grades)
    table.sort(names, function (n1, n2)
        return grades[n1] > grades[n2]  -- compare the grades
    end)
end

names = {"Peter", "Paul", "Mary"}   -- restore unordered state
sortbygrade(names, grades)          -- order by function

print "--- ordered ---"
print "- w/ function -"
for i,v in ipairs(names) do print(names[i], grades[v]) end
print "---------------"

This was some code I created, based on chapter 6.1. Here is the output, using the standalone version of Lua:

-- unordered --
Peter 8
Paul 7
Mary 10
---------------
--- ordered ---
Mary 10
Peter 8
Paul 7
---------------
--- ordered ---
- w/ function -
Mary 10
Peter 8
Paul 7
---------------

The order function has two parameters, a table and a function.

In Lua a function is an anonymous value, which can be assigned to a variable.

function foo (argument) end

is simply syntactic sugar for

foo = function (argument) end

This means you can use an anonymous function as the second parameter of the order function. This anonymous function should have two arguments, which are both an index for the table, and return a value that indicates which of the two table elements referred to by these indexes should go first.

In the code example, this piece of code is interesting:

function sortbygrade (names, grades)
    table.sort(names, function (n1, n2)
        return grades[n1] > grades[n2] -- compare the grades
    end)
end

The variable grades inside the anonymous function is neither local, nor global. It can be called an "external local variable", or--in Lua jargon--an upvalue.

Now I'm quoting from the text of chapter 6.1 of Programming in Lua:

Consider the following code:

function newCounter ()
    local i = 0
    return function () -- anonymous function
        i = i + 1
        return i
    end
end

c1 = newCounter()
print(c1()) --> 1
print(c1()) --> 2

Now, the anonymous function uses an upvalue, i, to keep its counter. However, by the time we call the anonymous function, i is already out of scope, because the function that created that variable (newCounter) has returned. Nevertheless, Lua handles that situation correctly, using the concept of closure. Simply put, a closure is a function plus all it needs to access its upvalues correctly. If we call newCounter again, it will create a new local variable i, so we will get a new closure, acting over that new variable:

c2 = newCounter()
print(c2()) --> 1
print(c1()) --> 3
print(c2()) --> 2

So, c1 and c2 are different closures over the same function and each acts upon an independent instantiation of the local variable i. Technically speaking, what is a value in Lua is the closure, not the function. The function itself is just a prototype for closures. Nevertheless, we will continue to use the term "function" to refer to a closure whenever there is no possibility of confusion.

So if I understand correctly, we should be talking about closures being assigned to a variable when we run code that defines a function. The code that defines the function is merely a prototype; we never see the actual closure expressed as code text, because it only exists at runtime.

Now that was hard for me to get my head around, and I still have to get used to thinking in closures, and having several instances of the same function, which are all different function values (sorry, closures). My brain hurts.

I guess I have to do some reading on the subject in Wikipedia before I continue in Programming in Lua. The subject is just too important to skip because it is so hard to understand. I was accustomed to and feeling comfortable with procedural programming, so functional programming seems to be a bit weird for me right now.

Wednesday, February 14, 2007

Programming in Lua - 3. Expressions

Well, the expressions chapter was a hard one to digest as a reader. I also saw an error in the text. It mentioned sin(0) as a valid expression, while I needed to type math.sin(0) to avoid throwing an error. Must be based on an older version of Lua.

For the rest, it was very theoretical, not much practical code, alas. This is a chapter, like chapters 1 and 2, you have to go through, hoping it will someday give you enough knowledge to produce better code.

Reference: Programming in Lua - chapter 3