lua-users home
lua-l archive

Re: [ANN] Lua 5.4.0 (alpha) now available

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


On 2019年6月27日 at 10:13, Dirk Laurie <dirk.laurie@gmail.com> wrote:
> Op Do. 27 Jun. 2019 om 13:08 het Dibyendu Majumdar
> <mobile@majumdar.org.uk> geskryf:
> I've been a Lua user for almost ten years, and I've succeeded in
> understanding and sometimes using every language addition in that
> time. Not so with <toclose>.
>
> My perceptions about it are:
>
> 1. It solves a problem encountered by a very small fraction of Lua users.
Have you ever a directory iterator? (e.g. for file in lfs.dir() ) If
so, you ran into this problem (maybe without realizing it).
To be quite honest, I've considered suggesting an ultra-minimalistic
approach for this whole issue: only provide to-be-closed behavior to
the `for` loop, and allow `for` to be used as a sort of `with`.
The thing about a so-called "minimalistic" langauge is that it has few
concepts, but those are often heavily overloaded.
The most obvious example is that a Lua table is an array, a hashtable,
an object etc.
Some languages have separate statements for `for` and `foreach`. Lua
overloads `for` with "numeric for" and "generic for".
So here's an idea for a third one, let's call it "resource for":
stat ::=
 ...
 for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end |
 for namelist in explist do block end |
 for namelist ‘=’ exp do block end |
 ...
(as you can see, it is syntactically a mix of the other two: you can
get multiple names on the LHS but a single expression on the RHS: if
it uses `=` but no `,`, it's a resource-for). It works in pseudo-code
like this:
do
 local x, y, ... = exp
 if x == nil and y == nil then break end -- only auto-breaks if
_all_ values are nil, so we can use libraries which use nil-err
errors.
 block
 if x then
 local xmt = getmetatable(x)
 if xmt and xmt.__close then
 xmt.__close(x)
 end
 end
end
Example usage:
for fd, err = io.open("file", "r") do
 if err then
 print("failed!", err)
 break
 end
 print(fd:read("*a"))
end
You could read this as a "for that only runs once because it has no
iteration second argument".
Generic-for would also be extended to support __close, of course.
HOWEVER, if we were to take a page from what's now mainstream syntax
in 21st century languages like Swift and Rust, and instead of
overloading `for` we overload `if`. The above example would turn into
this instead, which is super nice:
if local fd, err = io.open("file", "r") then
 print(fd:read("*a"))
else
 print("failed!", err)
end
Since this is new syntax, one could simply establish that the __close
check runs at the end of every if-local block.
-- Hisham

AltStyle によって変換されたページ (->オリジナル) /