---
title: "Introduction to luajr"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Introduction to luajr}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

**luajr** allows you to run [Lua](https://www.lua.org) code from R.

Lua is a lightweight, simple, and fast scripting language that is used in a 
variety of settings. The standard Lua interpreter is already reasonably fast, 
but there is also a just-in-time compiler for Lua called 
[LuaJIT](https://luajit.org) that is even faster. **luajr** uses LuaJIT.

This is **not** a guide to Lua or LuaJIT; it is a quick-start guide to 
**luajr** for people who already know how to program in Lua. See the 
[Lua web site](https://www.lua.org) for resources related to coding in Lua,
and the [LuaJIT web site](https://luajit.org) for resources related to
LuaJIT itself.

## Running Lua code: `lua()` and `lua_shell()`

```{r setup}
library(luajr)
```

To get a feel for **luajr** or to run "one-off" Lua code from your R project, 
use `lua()` and `lua_shell()`.

When you pass a character string to `lua()`, it is run as Lua code:

```{r}
lua("return 'Hello ' .. 'world!'")
```

Assignments to global variables will persist between calls to `lua()`:

```{r}
lua("my_animal = 'walrus'")
lua("return my_animal")
```

This is because **luajr** maintains a "default Lua state" which holds all global 
variables. This default Lua state is opened the first time a package function
is used. You can create your own, separate Lua states, or reset the default Lua
state (see [Lua states](#states), below).

Assignments to local variables will *not* persist between calls to `lua()`:

```{r}
lua("local my_animal = 'donkey'")
lua("return my_animal")
```

In this case, the second line returns `"walrus"` because the local variable 
`my_animal` goes out of scope after the first call to `lua()` ends, so the 
second call to `lua()` is referring back to the global variable `my_animal` from
before.

You can include more than one statement in the code run by `lua()`:

```{r}
lua("local my_veg = 'potato'; local my_dish = my_veg .. ' pie'; return my_dish")
```

You can also use the `filename` argument to `lua()` to load and run a Lua 
source file, instead of running the contents of a string.

Call `lua_shell()` to open an interactive Lua shell at the R prompt. This can 
be helpful for debugging or for testing Lua statements.

## Calling Lua functions from R: `lua_func()`

The key piece of functionality for **luajr** is probably `lua_func()`. This 
allows you to call Lua functions from R.

The first argument to `lua_func()`, `func`, is a string that should evaluate to 
a Lua function. `lua_func()` then returns an R function that can be used to call
that Lua function from R. For example, you can use `lua_func()` to access an 
existing Lua function from R:

```{r}
luaprint = lua_func("print")
luaprint("Hello, world")
```

Here, `"print"` is just referring to the built-in Lua function `print` which 
prints a Lua value to the console. You can also use `lua_func()` to refer to a 
previously defined function in the default Lua state:

```{r}
lua("function excited_print(x) print(x .. '!') end")
lua("return excited_print('Hello, world')")

xp = lua_func("excited_print", "native")
xp("Wow")
```

Or you can use `lua_func()` to define an anonymous Lua function:

```{r}
timestwo = lua_func("function(x) return x*2 end", "native")
timestwo(123)
```

Under the hood, `lua_func()` just takes its first parameter (a string), adds 
`"return "` to the front of it, executes it as Lua code, and registers the 
result as the function.

The second argument to `lua_func()`, `argcode`, is also very important. 
`argcode` determines how the arguments passed to the function from R are 
translated into Lua variables for use inside the function. 

The most important argcodes are `"auto"` and `"native"`. 

The argcode `"auto"` means that the parameter should be passed as a **luajr** 
type providing direct access to the R variable passed in. For example, with the 
argcode `"auto"`, an R numeric vector is passed as a `luajr.numeric` type, an R 
character vector is passed as a `luajr.character` type, and an R function is 
passed as a `luajr.rfunction type`. For a guide to **luajr** types, see the 
vignette [The luajr.lua module](luajr-module.html)

The argcode `"native"` means that the R value passed in should be converted to 
a native Lua type. For example, with the argcode `"native"`, a single number in
R like `2.5` is passed as a Lua number, a single string like `"foo"` is passed 
as a Lua string, and a list like `list(a = 1, b = 2)` or a vector like `10:12`
is passed as a Lua table.

For example, suppose you want to pass the R numeric vector `c(1.1, 3.3, 2.2)` 
into a Lua function from which you will return the biggest number in the vector.
If you want the numeric vector to come into your function as a `luajr.numeric` 
type, you could write:

```r
x = c(1.1, 3.3, 2.2)
my_max = lua_func("
function(x)
    local max = nil
    for i = 1,#x do
        if max == nil or x[i] > max then
            max = x[i]
        end
    end
    return max
end", "auto")
my_max(x)
```

If you want the numeric vector to come into your function as a Lua table, you
could write:

```r
x = c(1.1, 3.3, 2.2)
my_max = lua_func("
function(x)
    return math.max(unpack(x))
end", "native")
my_max(x)
```

where the above example takes advantage of Lua's built-in `math.max` function
that returns the biggest element from among all the arguments passed in.

The permissible arg codes are:

|Arg code         |Short form|Accepted R types |Resulting Lua type |
|:----|:---|:----------|:-----|
|`auto`           |`.`       |any | |
|`sexp`           |`S`       |any |`R.sexp` |
|`rfunction`      |`F`       |function |`luajr.rfunction` |
|`environment`    |`E`       |environment |`luajr.environment` |
|`logical`        |`L`       |logical |`luajr.logical` |
|`integer`        |`I`       |integer, numeric (coerced) |`luajr.integer` |
|`numeric`        |`N`       |numeric, integer (coerced) |`luajr.numeric` |
|`character`      |`C`       |character |`luajr.character` |
|`vector`, `list` |`V`       |list |`luajr.list` |
|`pointer`        |`P`       |external pointer |light `userdata`|
|`native`         |`$.`      |any native-compatible type | |
|`function`       |`$F`      |function or external pointer to Lua function |`function` |
|`boolean`        |`$L`      |length-1 logical |`boolean` |
|`number`         |`$N`      |length-1 integer or numeric |`number` |
|`string`         |`$C`      |length-1 character |`string` |
|`table`          |`$V`      |list or atomic vector |`table` |

Arg codes should be separated from each other by a comma, semicolon, or space 
within the string. "Short form" arg codes do not need to be separated. For 
example, `"S$L"` is equivalent to `"sexp, boolean"`. 

Above, the `$` prefix specifies "native type".

There is also the `!` prefix, which can be used to specify "strict" mode. In 
"strict" mode, there is no coercion between integer and numeric types, and 
`NULL` yields an error instead of `nil` when a Lua native type is requested.

The `&` prefix can be used to specify that an R vector type should be passed
by reference. When a vector (logical vector, integer vector, numeric vector, 
character vector, or list) is passed from R to Lua by reference, modifications 
made to the elements of that passed-in vector persist back in the R calling 
frame. For example:

```{r}
values = c(1.0, 2.0, 3.0)
keep = lua_func("function(x) x[1] = 999 end", ".") # passed by value
keep(values)
print(values)

change = lua_func("function(x) x[1] = 999 end", "&.") # passed by reference
change(values)
print(values)
```

Vectors can never be resized by reference; only their already-existing elements
can be changed by reference.

## Working with Lua States: `lua_open()`, `lua_reset()` {#states}

All the functions mentioned above (`lua()`, `lua_shell()`, and `lua_func()`)
can also take an argument `L` that specifies a particular Lua state that the
function operates in.

When `L = NULL` (the default) the functions operate on the default Lua state.

But you can also open alternative Lua states using `lua_open()`, and then by
passing the result as the parameter `L`, specify that the function operates in
that specific state. For example:

```{r}
L1 = lua_open()
lua("a = 2")
lua("a = 4", L = L1)
lua("return a")
lua("return a", L = L1)
```

There is no `lua_close` in **luajr** because Lua states are closed automatically 
when they are garbage collected in R.

`lua_reset()` resets the default Lua state:

```{r}
lua("a = 2")
lua("return a")
lua_reset()
lua("return a")
#> NULL
```

To reset a non-default Lua state `L` returned by `lua_open()`, just do 
`L = lua_open()` again. The memory previously used by `L` will be cleaned up at 
the next garbage collection.

## Further reading

For notes on how to create and manipulate R objects -- such as vectors, lists, 
and data.frames -- in your Lua code, see [the luajr.lua module](luajr-module.html) 
vignette.

