lua-users home
lua-l archive

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


"Egor Skriptunoff" <egor.skriptunoff@gmail.com>:
> On Fri, Jan 25, 2019 at 1:32 AM Dirk Laurie <dirk.laurie@gmail.com> wrote:
>> Every attempt to reduce the need for parentheses introduces a possible
>> ambiguity, whose resolution might after all require a semicolon.
>
> You are wrong here.
> Removing parentheses from the following expressions will NOT add any new ambiguity in Lua syntax.
>    ("str"):foo()
>    ({a=42})[foo]
> As you can see, these expressions are already a source of ambiguity due to they are starting with `(`.
> You can't make them more ambiguous than they already are :-)

That's an interesting rake! It's not even literal-specific, by the way:

> print("Starting work...")
> (workload or default):start()

This innocent-looking code will throw "attempt to call a nil value" when trying to call the result of print().
I think `_=` or `;` is better added *before the second line*, as that's the one causing the problem.

Allowing to omit parentheses around literals would only allow to step on the very same rake without
using an extra pair of parentheses. Having said that, having to type out slightly longer and uglier code
might be just enough of a deterrent, so there may be some sense in forcing the use of parentheses.

Also, note that this rake can be stepped on *only when a statement has no left side*, that is, when
there is no assignment. That only makes sense if a function is called for its side effects only.
String literals have no methods with side effects by default, and IMO chance that someone adds some
and starts using them *just because parentheses became optional* is pretty negligible.
A switch statement can also be implemented by constructing a table of functions defined in-place,
immediately indexing it and calling the result, but again, I don't think many would start doing that just
because the extra parentheses are no longer mandatory. All in all, I cannot come up with a good
example of this kind that would scream "That's why you cannot omit parentheses!"

When a literal or a parenthesized expression is *not* placed at the start of a statement, the above kind
of ambiguity is not possible at all. If allowing to omit parentheses would add any ambiguity at all, it
would likely have nothing to do with semicolons. In fact, most of the possible cases should already be
covered by "custom literals":

> function L(v) return v end
> print(L"%08X":format(address))
> f = L{io.stdout, io.stderr, logfile, devnull}[out_stream]

These can be used both with and without extra parentheses, and the results will be exactly the same.
The only difference between those L-prefixed and bare literals are that:

1. Prefixed literals can be indexed (with `.`, `:` or `[]`) and called directly, bare ones cannot.
   (Trying to index or call a bare literal always causes compilation error.)
2. Bare literals can be used as a sole argument to function call, prefixed ones cannot.
   (Trying to use a prefixed literal in this role would be interpreted as starting a new statement instead.)

Making parentheses around bare literals optional will remove the compile error and allow using
bare literals anywhere where prefixed ones can currently be used. The only possible problem is that
if the prefix was the only hint to Lua that a new statement is starting, as per comment for (2), then
using a bare literal instead would cause the same ambiguity that I described several paragraphs ago.
Again, I doubt that anyone who otherwise would prefix normal string or table literals like that
would opt to not do that for the sole reason of eliminating the extra letter.



I've learned quite a bit about the dark corners of Lua while participating in this thread, and my current
opinion is that allowing to omit parentheses around string and table literals should not cause any
real problems. It would allow for a bit nicer looking code in some common (and not quite) use cases:

> function string:boxed()
>   local t = "-":rep(#self + 2)
>   return "+%s+\n| %s |\n+%s+":format(t, self, t)
> end
> print('Some text in a box!':boxed())

However, it would not really give anything, except for eliminating a pair or two of parentheses from
time to time. No new use cases, no eliminated problems, just pure aesthetics. Whether it is worth
the effort and the potential risk that something somewhere goes wrong somehow, I don't know.

-- Evgeniy Zhabotinskiy