Calculator Community > Lua

[Lua]Advanced Topics and Cool Tricks

(1/2) > >>

Ashbad:
Hello:

I just went through a Lua tutorial to refresh my memory on how the syntax works and the method of how functions and tables specifically act in that.  So, I've decided to share some of these more Lua-specific ideals here, since many are just learning the language due to a recent spike in CX programming activity in the TI community.  So, since many only know the basics at the moment, I've decided to do my part and educate the masses of some of Lua's beautiful more advanced workings :)


Tables

You can think of a table as the only real class-like variable container in the Lua language (Lua can be expanded to work with OOP, but in my experience it is a very weak implementation and I'm not going to explain it in detail here).  Tables can be thought of as the 'universal container' since they can hold anything inside of themselves.  Tables can in a way be thought of as Structs in C, as they hold memebers in a group without class-like properties.  The difference however, is that tables are beautiful in the fact that they can hold just about anything you can think of.  They can hold variables, functions, and even other tables.  This programming style is a bit harder to grasp for people used to OOP programming, but I'll try to make it simple enough to change your view so you can grasp it ;)

Here is an example of a table:


--- Code: ---Table = {Apple = "Macintosh", Int_thing = 55, function foo() print("Hello") end, Letters = {a = "a", b = "b"}}
--- End code ---

This is all valid Lua code when instantiating a Table.  Like structs, members of these Tables (the things inside of them) can be called pretty easily:


--- Code: ---print(Table.Apple) -- prints "Macintosh"
--- End code ---

And similarly, when it contains other tables or functions, it can be chained like this:


--- Code: ---print(Table.Letters.a)  -- prints "a"
Table.foo()  -- prints "Hello"
--- End code ---

As you can see, this can be extremely useful and is in many ways similar to objects in OOP.  However, some differences from classes is that each time you activate one, it's an actual variable and is not treated like a "Class", since it's just a container and doesn't have finalization or instantiation methods or other things classes have.  It's also much more flexible with how things work.  HOWEVER, if you DO want to pretend it is OOP, you can fake it in a way by making it look Ruby Style.  In the Ruby Style of Lua, things are very much like Ruby in how tables are treated like classes and objects.  Below is an example of how a mainframe 'Class' table is made and how a new 'Instance' table is derived from that:


--- Code: ---String_thing = { -- our class
  value = "__empty__",
  function print_value()
    print(self.value)
  end
  function new(new_table_name, new_string) -- 'copy'-constructor
    new_table_name = self
    new_table_name.value = new_string
  end
}

String_thing.new(String_inst = {null}, "I'm a new string!") -- the actual instantiation
-- Now String_inst is now == to the 'class' String_thing  and is a new instance
--- End code ---


Anonimity in Functions

Anonymous functions are the pinnacle of functional programming and can be extremely useful in many cases.  Before I go into detail, I want you to know the difference between a normal function and an anonymous one.  A normal one can return a value in many cases and may execute code as well.  These are treated as functions as you normally are used to with Lua.  However, Anonymous functions are much different.  They are made to represent values, though with possible code to determine their value based on inputs.  In many languages like Python and Ruby, these are called either Lambdas or Procs.  In Ruby, it would be this (I'll use Ruby as an example as the Lua version is a bit harder to follow and can't be used as easily in this type of example):


--- Code: ---Foo = lambda {|value,root| value**root}
# the value of Foo is a lambda that equates to the input value to the root's.. root
Foo.call(2,16) # Foo is now equal to 65536, which is 2**16
--- End code ---

It's a bit less straightfoward in Lua, and I won't show a Lua example until I can get into the next fray: closures.


Closures

Closures in Lua are a bit like they are in other languages.  In Ruby (and maybe Python) they are called Procs -- they are basically embedded lambdas that serve no other purpose than returning a value that is not specifically attached to a variable at all.  An example is when you embed one into an actual function:


--- Code: ---function example(cells, generation)
  return cells + (function ()
    return generation % cells
  end
end
--- End code ---

In this case, we would be calling a lambda form within a function, making it a Proc on the spot.  In this, it simply returns (Cells + (Generation % Cells)) -- not a useful example, but a decently explaining one overall.  When you embed Procs inside of Procs, you are then fulfilling a convention called Currying:


--- Code: ---function example(cells, generation, apple)
  return cells + (function ()
    return generation % (function ()
      apple - cells
    end
  end
end
--- End code ---

Curry can be very useful but can also really make your code hard to follow.

On a side not, non-anonmymous functions can be used in an anonymous form, though what I mean by this is completely different in function (no pun intended) than what I said before.  Therefore, I'll just call them "namable" functions.  What am I talking about?  I'm talking about a powerful example of the flexibility of Lua function-calling conventions:


--- Code: ---apple = {show_good_stuff = print}
apple.show_good_stuff("Hello, world!) -- does print("Hello, world!)
--- End code ---

While using Namable functions like that isn't nearly as useful as other possible conventions, it can be very useful if you either want to rename a function or even a variable OR if you want to index functions in a table for quick access:


--- Code: ---function_list = {i1 = print, i2 = reverse, i3 = input}
function_list.i1("Hello World!")
--- End code ---


Polymorphic Class Tables

This is a broad set of concepts that I'm condensing down to only a small section.  You see, in Java and the like, you have things such as instanceof, interfaces, and more.  How do these work in Lua?

In Lua, determining types of instances is actually quite easy, but requires one more variable in each class:


--- Code: ---function instanceof(instance,class)
  return (instance.type == class.type) ? true : false
end

String_Class = {
  function new(new_inst, new_value)
    self.value = new_value
    return self
  end
  type = String_Class 
}
new_string = String_Class.new()
instanceof(new_String,String_Class) -- returns true
--- End code ---


As you can see, that's actually quite simple :)  However, interfaces are a bit different.  Interfaces work as modeling classes, so in a way they are 'classes of classes'.  Here is an example of setting up a class in sync with an interface:


--- Code: ---function SetupClassToInt(class, interface)
  for k,v in pairs(second_table) do first_table[k] = v end 
end

Int_Thanks = {
  function new()
    print "Hello!"
  end
  partof = "Int_Thanks"
}

function _partof_(inter,class)
  return (class.partof == inter.partof) ? true : false
end

Class = {null}
SetupClassToInt(Class,Int_Thanks)
_partof_(Class,Int_Thanks) -- returns true
--- End code ---

It's simple once you get into the swing of things ;)


Thanks for putting up with me for now!  But, don't think I'm gone yet, I've only gone over a few cool little things can in Lua -- I plan on ading more later!  Things to stay tuned for:

- Polymorphic Class Tables
- Inheritance with Table-Based OOP
- Tricks with Lua glitches
- And more!  Suggest what you want, I'll post it! :)

For now, your Lua friend,

~ Ashbad

Levak:
We were working on it x)
http://www.inspired-lua.org/category/tutorials/starting-in-lua/

Adriweb:
Well this one is good too, so I think we can put both :)

We'll have to do some formatting but it's great:)

Ashbad:
thanks, you both :) I appreciate the feedback immensely.

Levak:
But I think, this is a Lua oriented Tutorial, not a real TI-Nspire Lua oriented one.
But it is a real good one to find some tricks I guess !

Navigation

[0] Message Index

[#] Next page

Go to full version