lua-users home
lua-l archive

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


this is a small idea for a new language feature.
What are your opinions?


HTML version:

Lua should add arrow operators(`->`, `=>`) that allow to use functions like member
functions without the use of monkeypatching.

== Problem

Existing basic types such as `number` and `string` require monkeypatching to add
member functions. Tables can have any function as a member that can be called with
the dot operator(`.`) or the colon operator(`:`). The dot operator provides access to all
objects that are stored in the table, functions or attributes. The colon operator allows
to call a function that is part of a table, and pass the table itself as the first parameter.

The solutions for basic types and tables have some downsides. The dot operator
requires the table itself as a parameter, the colon operator still requires the function
as a value of the table itself, monkeypatching is powerful but can have global
consequences[1][2] that are hard to manage.

In all other cases you have to use a function as a free function with the value as a
parameter. While it is not a big deal for single function calls, the chaining of functions will
always lead to a reverse call order:

round( cosh( math.exp( 1 ) ), 7 )

This is inconvenient to read and the only thing that is required in this case is to pass
the result of the function as the first parameter to the following function.

== Solution

A new arrow operator(`->`) would allow to write the functions in the same reading order
as they are called:

math.exp( 1 )->cosh()->round( 7 )

The "->" operator passes the value/result on the left side as the first parameter of the
function on the right side. This behaviour would be quite similar to the existing colon
operator for tables, without the requirement that the function is part of a table.

If a function returns two or more values, the "->" operator just passes to the first value
to the following function. The additional "=>" operator would allow to pass two values
to the following function.

local function twovalues()
   return "a", "b"

twovalues->print() -- prints: "a"
twovalues=>print() -- prints: "a\tb"

If a function returns just one value, the "=>" operator should pass a *nil* as a second value.
Lua allows more than two return values, but I have difficulty to imagine many cases with
more than two values where someone would want to write code in that way.

It may look like that tables do not benefit much from the new arrow operators, but the ability
to use non-member functions like member functions with "->" can potentially reduce the
temptation to add functions as member, and allows to call all functions like member functions
in C++ - improving the code in general as a result.[3].

Just to be clear this proposal has nothing to do with the arrow functions you maybe know
from JavaScript[4]. The idea is based on the hidden parameter behaviour that the ":“ operator

== Safe Navigation

The simple injection of function calls allows us also to create functions that are used like a
language extension. Lets take the safe navigation operator example from chapter 5.5 in
"Programming in Lua Fourth edition“[5].

The recommended replacement for the "?." operator in C# looks like this:

E = {}
zip = (((company or E).director or E).address or E).zipcode

With the arrow operator it is possible to imagine the following solution:

function sv( v ) return v or {} end
zip = company->sv().director->sv().address->sv().zipcode

This approach adds three function calls, but I find this code easier to read and write.

== Example

The attached example should demonstrate how the use of the arrow operators is imagined.

== Sources

- [1]
- [2]
- [3]
- [4]
- [5]

Attachment: example.lua
Description: Binary data