lua-users home
lua-l archive

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




On 2019-01-24 4:50 a.m., Жаботинский Евгений wrote:
"Kenneth Lorber" <keni@his.com>:
[...]

  function string:alike(other) return self:lower() == other:lower() end
  s = "WomBat"
  s:alike"wombat"
true
  "wombat":alike(s)
stdin:1: unexpected symbol near '"wombat"'

Since according to the manual there is one metatable for strings and the string library sets it, we're missing the opportunity to write:
  io.write("This is the value: '%d'\n":format(x))

There are other useful cases, but this is the one I think is best (that is, useful and clear) should be enough for people to tell me this is a bad idea :-)

Opinions please: Why is letting a string literal be more like a string a good or bad idea?

Thanks,
Ken

[1] http://lua-users.org/lists/lua-l/2007-05/msg00059.html
[2] http://lua-users.org/lists/lua-l/2007-03/msg00493.html

My opinion is that we have the wrong syntax sugar.

When calling functions, we generally pass *multiple* values as parameters to a *single* callable.
Therefore, I think most would expect "as little as possible" as the value of what to call, and some sort of delimiter after the values to pass to it.


* >  print "Hello".."World"
* >  print s1..s2

According to my understanding, both lines look like they do the same, while first does not and the second does not compile.
The only delimiter visible here is the end of the line. Or at least I see a string literal as a single value, as opposed to text between delimiters.
Therefore, printing the result of concatenation is expected.
Instead, it calls print on the first string, and then concatenates the result with the second, which currently fails in the best case.
Plus, I can't think of a good use for this feature. The obvious deprecated-python-like `print "Message."` cannot even be used with format!


* >  s = ">".." %d":format(v)
* >  s = s.." %d":format(v)
* >  s = s..f:format(v)

To me, the above lines look like they definitely do the same kind of thing.
The last one does exactly what it looks like to me, while the others do not compile as of yet.
And I'm pretty sure very few, if anyone, would expect the last line to call format on the result of concatenation.

In all languages I can think of, you have to use parentheses whenever you need a method or a field of something that isn't a single value or a field.
At the same time, you generally don't need them for a single value. Some examples:

* >  // C++:
* >  string s = "Hello";
* >  int l = s.size();
* >  int p = (s + "World").find("oW");
* >  //int t = "Hello".size() -- Makes no sense, since string literal is not a string object, but (const char*) that has no methods.
* >  const char *p = "Hello!" + 2; // Points to the third letter. This shows that string literals are just normal values, I guess?
* >  struct S a[10];
* >  a[1].b.c
* >  (a + 1)->b.c // Same as above
* >  a->b == a[0].b // true

* >  # Python:
* >  sys.stderr.write('0x{:04X}: {:s}\n'.format(offset, msg))  # 0xBEEF: Found it!
* >  s = s+' {:02X}'  # Add hex representation of a byte to s
* >  print("Numbers: " + ", ".join(a))  # Numbers: 4, 8, 15, 16, 23, 42
* >  (delimiter + " ").join(['First', 'Second', 'Third'])  # First? Second? Third
* >  (42).to_bytes(2, 'little')  # 0b'\x2a\0'
* >  # 42.to_bytes(2, 'little')  -- Does not work, unlike 'a'.upper(), probably because dot could also be a decimal point.

Custom literals:

local foo = u128"10000000000000000000000000000000000000"
local bar = re"[A-Za-z_][A-Za-z0-9_]*"



So, to sum up this overly long explanation, I think allowing to omit parentheses around string literals for method calls on them would be nice.
Since Lua uses colon to denote method calls, that could even be allowed for numbers, in case someone gives them a useful metatable.
On the other hand, calling functions on strings without parentheses looks ambiguous and should be deprecated IMO.
Basically, I think that string literals should be treated the same way as variables holding strings.


Note, however, that calling functions with single table as an argument without extra parentheses is a bit different:

* >  table.concat{a, b, c}
* >  fun{"Yes!", what, 2, why=42}

The curly braces here look quite a bit like parentheses. They visually delimit the arguments.
It actually looks more like passing several values, as opposed to single table, so it's much easier to not expect any more args to follow.
I personally see this syntax more like Python's *varargs plus **kwargs usage.
This can definitely be useful, since Lua does not support named arguments or **kwargs natively.


Thanks for reading.
-- Evgeniy Zhabotinskiy