lua-users home
lua-l archive

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




Le dim. 24 mai 2020 à 19:55, Francisco Olarte <folarte@peoplecall.com> a écrit :
Philippe:

On Sun, May 24, 2020 at 2:23 PM Philippe Verdy <verdyp@gmail.com> wrote:
>
> Oh, and did I say that I hate the notation forcing us to use [] for keys in table constructors ?
> -  {[10]=11}, why not just  {10=11} ???
> -  {['a string']='something'}, why not just {'a string'='something') ?

> The notation using [] is just needed when keys are expressions with arbitrary types, but it should never be needed if keys are static strings or numbers.

No, it is not. In your example above, how do you differentiate betwee
"1".."0" and 5+5 ( both written as 10 )

by the quotes!! I do not mean that {10 = 11} with an number key is the same as {'10' = 11} with a string key
And {'1'..'0' = 11} may be valid and equivalent as well to {'10'=11} or today's {['10'] = 11} with a string key (but not kind of expressions may be used without any surrounding parentheses)
And {5+5 = 11} would also be valid and equivalent as well to {10=11} or today's {[10] = 11} with a number key (but not all types of expressions may be used without any surrounding parentheses)

I confim you never need the brackets in table constructors, they are unnecessary pollutions, and you could still use subexpressions in parentheses if this creates a problem. if you do't want the compelxity of permitting some kind of expressions, you can restrict the absence of parentheses only for the case of simple string constants, or signed numbers, or a function call (including with currified), or a subexpression in parentheses:

{sin(x) = 1} or {sin x = 1} are also valid and equivalent, this is a finction call returning a value to be used as a key (if the value is nil, the table constructor will fail with an error, other expressions further down in the list of members may not even be called, the table object will not even be created; if it was created to store intermediated results, it will be released and not returned to the caller catching the error, and it will not even be passed in the error object)

but {local x = 1} is not equivalent. It is invalid today but may have an evident utility to create self-referencing tables or subtables where a local varaible declared at the beginning of the table construstor, before the list of members, could be assigned with a reference to the current empty table being built like: x= {local t = :self; 10, t, } which means that it builds a table with two items such that x[1]==10 and x[2]==x, and where ":self" is a reference to the most local subtables where the _expression_ is evaluated, stored in a local variable t (t is not part of the list of members, but part of the table of variables managed by the syntaxic table constructor, which creates a new lexical scope limited by the {} pair, so that the second member of the table constructor can use this variable t  in a normally evaluated _expression_)

You could declare one or several subtables and assign them into a local declaration statement or in other assignement, then use the subtables to build the current table tocreate complex graphs:

t={local u,v={10,11,}, {20,21, u} ; u[] = v ;  u, v}

where
  t[1] == u == {10,11,v} and t[2] == v == {20, 21, u}, except that u and v are hidden outside the local constructor so that you can only see that:
  t[1] == {10,11,t[2]} and t[2] == {20, 21, t[1]}, or
  t[1] == {10,11, {20, 21, t[1]}} and t[2] = {20, 21, {10,11,t[2]} }

Such recursive tables (with cyclic graphs using backward references to an ancestor node, or common subbranches using backward references to a sibling branch at arbitrary depth even if it is not a cyclic graph) are very common in the DOM API for HTML documents, and even inside the Lua library



> But in fact, given that "=" is reserved for assignment instructions, the [] is never needed syntaxically: in table constructors, the "=" replaces the assignment, but it is in fact a true assignement (of a key), so this shouldbe valid as well:
> -  {sin(x) = 1}, i.e. the same as today's {[sin(x)] = 1}

And how do you parse "{a=1,b=2}", as ["a"]=1,["b"]=2 or as ["a=1,b"]=2
or, if you allow the same extension in values, ["a"]="1,b=2" ?

I parse {a=1, b=2} as if it was {'a'=1, 'b'=2} (the former is possible only if quoted literals have the syntax of an identifier and is not a reserved keyword)
I also accept the legacy syntax  {['a']=1, ['b']=2} even if brackets are superfluous.
I also accept the syntax  {('a')=1, ('b') = 2} which are another form where expressions used for keys are between parentheses.
The brackets or parentheses can be removed if the _expression_ is not reduced to a single identifier; if this is a single identifier it is still considered as a literal string key, not as a variable reference (if you need a variable reference, put it in parentheses or in legacy brackets.


You could come up with elaborate rules for all of that, but it is
normally better to limit to simple specs, like unbracketed keys can
only be identifiers and always parsed as strings.

By the way, your "true assignment" will force you to write {"a"=1} for
the current {a=1}, i fact unquoted names would be interpreted as vars.

No!!! And even today they are NOT interpreted as vars but already as literal string keys. Today to make the interpreatation as vars you need the brackets, it could have been the parentheses like for all other subexpressions...