lua-users home
lua-l archive

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




Le lun. 26 nov. 2018 à 11:30, Soni "They/Them" L. <fakedme@gmail.com> a écrit :
The classic Cratera[1] `foo:[component].method()` (note the colon) syntax.
[1] https://bitbucket.org/TeamSoni/cratera

Write it in Lua as
  foo[component].method(foo), or
  foo[component]['method'](foo)

I don't see what the "cratera" fork brings which is not already part of standard Lua...
You can still use an _expression_ to replace any identifier, just replace the " .identifier " syntax by " ['identifier'] ".
The colon is just a syntaxic sugar in Lua for passing an object (a table) in the first parameter of a function which is one of the property values of the object). And there's not even any need to change the VM to support it, you can always rewrite the _expression_ with colon into a function call.

The interest of the colon however is that this common _expression_ (for computing the reference of the object) is coimputed only once and duplicated (kept in an hidden temporary variable or register) before first dereferencing it to extract one of its property (which is a function) and then reuse it as the first parameter to call the function.
It only exists because Lua does not "directly" allow using assignments in the middle of an an _expression_.

But there's a way to perform an assignment in a local variable in the middle of an _expression_ in standard Lua. For example the following is not allowed by the syntax:

  y = (local x; sin(x = arbitrary_expression()) + cos(x))

But you can rewrite it using a local function in a closure to perform the assignment by calling that function:

  local x;
  y  = sin( (function(){x =  arbitrary_expression()})() ) + cos(x)

or more equivalently (to limit the scope of "x" inside the _expression_) as:

  y  = (function() {local x; return sin( (function(){x =  arbitrary_expression()})() ) + cos(x)})()

Here also you don't need any change to Lua or its interpreter or compiler, or to the VM. The possibility of performing asignments in the middle of expressions, and even adding local varaible declaration would just make it more easier (temporary variables are frequently needed to store the results of common subexpressions that you MUST NOT evaluate multiple times without introiducing side-effects, notably if the "common subexpression contains function calls, for example performing some I/O or modifying other referenced objects or other objects hiden in the function closure).

Having the possibility of directly declaring local variables in the middle of expresssions would be useful and productive (and it would perform various optimizations that are hard to realize in interpreters and compilers, that have to perform complex matching search to detect common subexpressions and check if their semantics is really equivalent).