Skip to contents

Takes any Lua expression (as a character string) that evaluates to a Lua function and provides an R function that can be called to invoke the Lua function. Instead of a character string, you can also provide an external pointer to a Lua function (see examples).

Usage

lua_func(func, argcode = ".", L = NULL)

Arguments

func

A character string with a Lua expression evaluating to a function, or an external pointer to a Lua function.

argcode

How to wrap R arguments for the Lua function.

L

Lua state in which to run the code. NULL (default) uses the default Lua state for luajr.

Value

An R function which can be called to invoke the Lua function.

Details

Any R type can be passed to a Lua function. The R types that have special support in luajr are: NULL, logical vector, integer vector, numeric vector, character vector, list, function, environment, and external pointer.

The parameter argcode is a string that specifies type handling for each argument of the Lua function. The last type is repeated when there are more arguments than specified types.

To receive a luajr.logical type in Lua, use the argcode logical or L. Similarly, luajr.integer is specified with integer or I; luajr.numeric is specified with numeric or N; and luajr.character is specified with character or C. luajr.list is specified with list, vector, or V.

To receive a luajr.rfunction type, use rfunction or F. To receive a luajr.environment type, use environment or E. To receive an R.sexp type, use sexp or S.

To pass any R type as "closest available" type from the above, use the argcode auto or ".".

Argcodes should be separated by commas. If you are using a "single-character" argcode like . or S, there does not need to be a comma following it.

You can also receive R values as Lua native types. Specifically, the argcode function corresponds to a Lua function; boolean is a Lua boolean; number is a Lua number; string is a Lua string and table is a Lua table. pointer or P passes an external pointer (EXTPTRSXP) as a Lua light userdata. The argcode native selects the closest available native type.

Additionally, the prefix $ specifies that the type should be passed as a Lua native type. So $auto is equivalent to native and $C is equivalent to string.

Note that native scalar argcodes (e.g. $L, $I, $N, $C, boolean, number, string) do not preserve R's NA values, because Lua has no NA concept: an R NA of any type is passed as Lua nil, which a non-strict argcode silently treats as missing. Plain NaN values (e.g. from 0/0) do survive as Lua NaN because they are distinct from R's NA_real_. To preserve typed NAs on a round-trip, pass values through a luajr vector type (e.g. luajr.numeric, luajr.logical) instead of the native scalar form, and read individual elements in Lua via v(i) (which returns a length-1 vector of the same type rather than a bare scalar).

The prefix ! specifies strict type handling (i.e., error if the type cannot be converted). ! also yields an error on passing NULL if the argcode specifies a Lua native type (otherwise, NULL gets passed as Lua nil).

The prefix & can be used with logical, integer, numeric, character, or generic (list) vectors and specifies that the value should be passed by reference. Vectors passed by reference can have their elements mutated in Lua code, but they cannot be resized.

When the function is called and Lua values are returned from the function, the Lua return values are converted to R values as follows.

If nothing is returned, the function returns invisible() (i.e. NULL).

If multiple arguments are returned, a list with all arguments is returned.

Vector types (e.g. luajr.logical) are returned to R as the corresponding R vector. A luajr.list is returned as an R list. Vector and list types respect R attributes set within Lua code.

A table is returned as a list. In the list, any table entries with a number key come first (with indices 1 to n, i.e. the original number key's value is discarded), followed by any table entries with a string key (named accordingly). This may well scramble the order of keys, so beware. Note in particular that Lua does not guarantee that it will traverse a table in ascending order of keys. Entries with non-number, non-string keys are discarded. It is probably best to avoid returning a table with anything other than string keys, or to use luajr.list.

A Lua string with embedded nulls is returned as an R raw type.

A function is returned as an external pointer, which itself can be converted into a function that can be called from R, by passing it through lua_func() as the func argument.

Examples

# use with a character string
squared <- lua_func("function(x) return x^2 end", "$.")
print(squared(7))
#> [1] 49

# use with an external pointer to a Lua function
times2ptr <- lua("return function(x) return 2 * x end")
print(times2ptr)
#> <pointer: 0x10dab0b10>
times2 <- lua_func(times2ptr, "$.")
print(times2(14))
#> [1] 28