lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

> Not very useful examples I know, I'm sorry.
> I guess writing code that ends up stating f(x)() is a bit odd.

OK, here are some more useful examples.

1) using assert to catch syntax errors on loaded scripts:


What is happening here? As the Lua manual says, loadfile() "Loads a file as a Lua chunk (without running it). If there are no errors, returns the compiled chunk as a function; otherwise, returns nil plus the error message."

assert() will throw an error in the second case, where there was a syntax error. That works well, because assert will use the error message produced by loadfile(). If there are no errors, assert returns its first argument, which is "the compiled chunk as a function". So we need to call the function to get the script to actually happen. The last () does just that.

2) "Precomputing" expensive function calls.

math.log() provides the natural logarithm of its argument. If I wanted something more general, I could define the following:

  function mylog(base, x) return math.log(x) / math.log(base) end
  > =mylog(10,100)

However, it is likely that I am going to use this function a lot with the same base. So what if I write it like this:

  function mylog(base)
    local logbase = math.log(base)
    return function(x) return math.log(x) / logbase end

Now, I can call it like this, if I want to:

   > =mylog(10)(100)

But I can also save the computation of math.log(10) as a function:

  > log10 = mylog(10)
  > =log10(100)

In fact, I can do even better: I can "remember" math.log as a local and avoid two table lookups:

  function mylog(base)
    local log = math.log
    local logbase = log(base)
    return function(x) return log(x) / logbase end

The combination of these optimisations is that computing a million base-10 logarithms goes from 3.44 seconds to 2.1 seconds.

3) Making syntax "look nicer"

A classic configuration-file issue: I want the user to be able to put something like this in her configuration file:

Location "/home/reb/files" {
  ScanFrequency = 10,
  Match = "%.jpg",
  Action = "">

Of course, that is a matter of personal preference. But it is easy enough to implement:

  function Location(loc)
    return function(options)
      -- do something with loc and options