lua-users home
lua-l archive

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


This is a simple syntactic sugar addition that would make code a lot
easier to maintain and refactor, and make idioms much clearer. I've been
thinking about how I'd want something like this for a long time, and I
think I've finally come up with how it could work.

The idea is simple: allow a fixed character on the right-hand side of an
assignment statement to refer to the left-hand variable(s). For example,
if I have a variable like this:

    local extremely_long_variable_name = 1

and I want to increment it by 1, I have to type its name twice:

    extremely_long_variable_name = extremely_long_variable_name + 1

If there was a shorter way of describing the variable being assigned
(let's use "@" as an example), this code could be much simpler:

    extremely_long_variable_name = @ + 1

Of course, Lua allows for multiple assignment in a single statement, as in
the classic swap function (we'll add another variable to demonstrate):

    local ridiculously_long_variable_name = 2

    extremely_long_variable_name, ridiculously_long_variable_name =
      ridiculously_long_variable_name, extremely_long_variable_name

So, how to handle this case? Well, we can have a slightly expanded
notation to refer to the variables in order on the left of the assignment
by suffixing their ordinal position. The classic Lua swap mnemonic thus
becomes

    extremely_long_variable_name, ridiculously_long_variable_name = @2, @1

(We let @ unadorned be syntactic sugar for @1 since most assignments are
single, not multiple, and it keeps the idioms cleaner.)

Of course, that doesn't address quite all of our use cases. For instance,
when we're doing something like linked list manipulation, we want to refer
back to our container in the expression (imagine the relevant variables
are set up already):

    linked_list_node.head = linked_list_node.tail

This could be addressed by adding a second level of rereferencing, with a
second at:

    linked_list_node.head = @@.head.tail

In fact, if we can be so bold as to allow left-of-assignment references on
the left as well, the scenario where we reverse the direction of a node
could be written as:

    linked_list_node.head, @@.tail = @2, @1

Of course, indexes are often multi-level, and it's a lot of redundancy to do:

    system.network.interfaces.eth.available.stats.number =
      #system.network.interfaces.eth.available.handles

And writing @@ instead of "system" doesn't save us much there. As such,
the second-level rereference would also be able to take an ordinal, this
time referring to levels of reference (from the base) to duplicate. Using
a levels-of-reference ordinal, the above could be shortened to:

    system.network.interfaces.eth.available.stats.number = @@5.handles

(If that's too opaque to read, you could just leave off a re-referenced
level and rewrite it explicitly as a location hint, eg.
"@@4.available.handles".)

Of course, you can use both assignment-order and level-of-assignment
ordinals simultaneously:

    tree_branch.left.left, tree_branch.right.left = @2@2.right, @1@2.right

How does this sound? Are there any massive glaring holes in this syntax
I'm over looking? Does it sound Lua-y enough?

---

I know it sounds over-engineered and opaque, but I really feel it's worth
it to be able to make immutable functions mutable through a simple
sequence as memorable as the "=@:" mnemonic:

    sanitized_domain_name=@:lower();