[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: [FUN] A bit of code golfing
- From: "Soni L." <fakedme@...>
- Date: Fri, 30 Sep 2016 18:27:40 -0300
On 30/09/16 05:38 PM, Egor Skriptunoff wrote:
On Fri, Sep 30, 2016 at 11:12 PM, Soni L. <firstname.lastname@example.org
I'd suggest to redefine the interpretation of zero value for
"index_from" argument of string:sub.
The documentation may look like the following:
Positive indexes 1, 2, 3... count from the beginning of
Negative indexes -1, -2, -3,... count backward from the
end of the
Index 0 has special meaning, its semantic is different for
"index_from" and "index_to" arguments:
index_from = 0 means "the index after the last character
index_to = 0 means "the index before the first character
In other words, the "rule of maximum restriction" holds.
There are two related Lua idioms: for any non-negative N
length N is ":sub(1, N)" and suffix of length N is ":sub(-N)".
"s:sub(k,0)" and "s:sub(0,k)" are always empty strings for any
s and k
Zero index always "kills" the substring.
This property is quite understandable for beginners,
descriptive and memorable.
Which is stupid if you consider all the things from numeric for,
table.move, table.unpack, table.concat, etc. Remember, just
because strings don't support index 0, doesn't mean they aren't
consistent with tables. Even # is consistent between strings and
tables (however, strings don't have a concept of nil).
What consistency you are talking about?
Unlike the "string" library, "table" library DOES NOT have the
possibility to use negative indexes for counting backwards from the
end of a table.
For example, table.unpack(t, -2) DOES NOT return two last elements of
There is no "consistency" that may be broken.
And there is nothing to change in implementation of "table" library.
There are many ways to look at this problem.
Technically speaking, a purist might even argue that ("a"):sub(1,3)
should result in "aaa" (e.g. me). Or that ("abc"):sub(1,4) should result
Also, don't forget select(). Never forget select(). select() even takes
the string "#" as a valid index.
But hey, select(), strings and files all deviate from tables, which are
the standard. Note how select, strings and files have no meaningful
concept of negative indices - they're exceptions. Thus, handling
negative indices exceptionally makes sense. But you should still aim for
consistency wherever possible.
I don't know what the Lua devs think. But it seems they do everything to
keep things consistent, only applying exceptions in exceptional
You might argue select(0) should return the length, instead of
select("#"). Or even select("n") for consistency with table.pack(). You
might argue table.pack() should have ["#"] as the length, not ["n"] -
for consistency with select().
I'd even go as far as saying str:sub(0,0) should return the full string,
unmodified. But that'd be only to fully oppose your argument.
Also, there's a fine line between a purist and a... someone who preaches
consistency. And idk where it is.
And don't forget, it'd also require a change to string.find,
string.gsub, string.gmatch, string.match, string.byte, etc
basically anything that takes an index.
Yes, "string.byte" should be modified the same way as "string.sub" as
it uses the same rules for specifying an interval of indexes.
But there is absolutely nothing nothing to change in implementations
of string.find, string.gsub, string.gmatch and string.match.
string.find, string.gsub, string.gmatch and string.match all take a
starting index, which can be negative.
PS: My personal favorite would be to just error() if the starting index
was 0. Would help catch tons of off-by-ones.
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.