lua-users home
lua-l archive

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


On 30/05/2020 10:24, Sean Conner wrote:
It was thus said that the Great Lorenzo Donati once stated:
On 29/05/2020 22:57, Sean Conner wrote:
It was thus said that the Great Phil Leblanc once stated:
When os.exit() is called, by default the finalizer for <close>
variables is not executed. If the second (optional) argument to
os.exit() is true, then the Lua state is closed, and finalizers are
executed.

I didn't realize that!
  In Lua 5.1, os.exit() calls exit().  In fact, the function is quite short
and reproduced here:

[snip]

  The problem is that the Lua state isn't cleanly closed.  If one wants to
cleanly close the Lua state upon os.exit() in Lua 5.1, one would have to
register a cleanup function via atexit().  Something like this:

[snip]

  This may have been an oversight on the Lua team, but as they have always
stated, the lua exectuable has *always* been an example of how to embed Lua.
And on most modern systems (POSIX definitely, possibly Windows these days),
the operating system will reclaim any resources used by a process upon
shutdown *anyway*.

Interesting.

  This was rectified with Lua 5.2, but to remain compatible with Lua 5.1
code, they decided to add a parameter to os.exit() to indicate a clean
closing of the Lua state, so the function now looks like:

[snip]
  Why they decided to keep this level of backwards compatability when they
drastically changed how modules and global variables work between 5.1 and
5.2 is beyond me, especially when a workaround for Lua 5.1 (as illustrated
above) was available.

Yep, I remember the gist of that change, although I didn't know the 
implementation details.

  But we have what we have.

I agree (reluctantly) on maintaining the backwards compatibility, but
<close> finalizers are different things. I would find rather unexpected
for them non being called on exit.
  Technically speaking, they don't leave the scope.  The Lua VM doesn't know
that os.exit() actually leaves the scope (or rather, that it leaves the VM
entirely).  To the Lua VM, this:

	do
	  local x <close> = io.open("foobar")
	  os.clock(0)
	end -- now we leave scope, x is closed

and this:

	do
	  local x <close> = io.open("foobar")
	  os.exit(0)
	end -- now we leave scope, x is closed

are the "same"---a to-be-closed variable is created, a function (from the
'os' table) with one parameter is called, then the scope ends, so call
x:__close().

I didn't know that, interesting. I didn't follow the development of Lua 5.4 closely. I would have guessed that any (non-emergency/non-fatal) mechanism that could force the VM to shut down, would force __close to be called. After all, that's the main application of RAII: ensure proper resource disposal in all cases (except "end-of-the-world" scenarios, of course).

  At least, I *think* this is the case---I haven't actually tested this, but
I think my reasoning is sound on this.

If one really wants NOT to call __close on exit, it would be better to
add another argument to exit (I know, ugly), or maybe define a new
behavior for exit when the second arg is a string, so that the string
specifies what to call or what not, e.g.:

os.exit( exit_code, 'noclose, nogc')
  I'm not sold on that.
Yes, I admit it's not particularly clean nor cute. And I don't like it 
too much, too. It's the first thing that came off the top of my head. 
Maybe someone could come up with something better.
Moreover, imagine the confusion when integrating different codebases,
which is not uncommon in Lua ecosystems, with all the different small
libraries out there.

If everyone had their own safeexit, with different signature and name, a
real hell!
  Is this a real problem, or a hypothetical problem?

More of an hypothetical one, but I've grown to be a very defensive 
programmer through the years. And I always try to work out the worst 
scenarios, at least based on past experiences.
__close is part of a safety mechanism. We have coped with its absence in 
other ways. The only advantage over the "old style" is that now you 
don't have to follow so rigid a discipline when you write your code, and 
the code is more elegant, since you could program your "finalization" 
routine upfront.
The only new mechanism is the /automatic/ call to __close in cases where 
coding disciplines is not enough, that is abnormal exits like exceptions 
and os.exit. If it doesn't work for exit BY DEFAULT, that's a big safety 
hole. You could force yourself to write os.exit(code, true) every time, 
but that's, again, coding discipline (which __close was meant to relax).

<rant>

Anyway, the manual should definitely point out this caveats more explicitly. Maybe I missed something, but there is no clear statement that __close WON'T be called on a normal os.exit() call.
To get that you should perform quite a convoluted inference: reading 
os.exit you should infer that a "Lua state" is something you need to 
know about (which is not a concept exposed to Lua side). Then you should 
dig into the C-Lua part of the manual and discover what a Lua state is 
and that when it is closed it will automatically call __close.
I.e. you must end up reading lua_close docs. And note that there is no 
direct link between __close docs and lua_close (OTOH there is a 
reference to lua_close in the GC section of the docs, end of 2.5.3).
Too much for a "pure" Lua programmer, IMO.

It's something of a pet peeve of mine to play the part of the "poor 'pure' Lua programmer", although I can't define myself like that (even if I don't use Lua C API regularly, and I'm no C guru, I can understand what's happening under the hood).
I really think Lua should be more widespread, and a good ref man that 
can be used by motivated users to learn the language (without knowing a 
single line of C) is a mean to that end.
BTW, I think that's one of the selling point of Python, which is all the 
rage now. I know Roberto doesn't think like that, but I must say that 
if, when I started to learn Lua /using just the refman/, I hadn't known 
C/C++ I would have been scared away by just reading the docs of os.date 
that told me to go look for strftime to learn how to format a date in Lua.
Heck! What does it mean "C strftime" to a newbie?!? Even that name 
'strftime' is not a comprehensible name, but a bunch of letters spliced 
together (thank you, C)! At least a link to, say cppreference.com could 
be a good hint.
I know the mantra "go buy PiL to be hand-held", but that's for people 
who have some money. Lots of people picked up Python because of the 
combination of (a) Completely free and open (Lua has it), (b) lots of 
good libraries ready to use with no hassle (Lua is far from that stage) 
(c) Good FREE docs for newbies all in one place (Lua is not there).
Moreover, in the age of the Internet, having to pay for tech docs is a 
bad marketing move.
There is a reason why big hardware corporations (e.g. chip 
manufacturers) put their datasheet online for free (and lots of 
application notes that are university book level quality): if people 
don't know your technology, they won't buy it and will look for 
companies that won't hold critical information before you buy.
I know of hardware/firmware engineers that get pissed off if to download 
a datasheet they even have to free-register with the company!
I know that for an open-source, free project the analogy is a bit 
stretched: you don't "buy" anything from Lua Team.
But, anyway, the underlying market forces are just the same: people 
won't pay for information they don't know it will be useful for them. 
Especially if they have a free alternative; even if it's a /worse/ 
alternative. Lots of time people choose known worse alternative over 
good ones that they know little about. It's psychology, babe! If you 
want people to use Lua, you should strive to convince them it's good for 
them. And C /is/ scary (for good reasons).
And having more people using the language is also a marketing booster, 
because then it becomes easier for a firm to adopt the technology 
because there are lots of programmers around (and you are not locked-in 
to some people you can't hope to replace, if the need arise). And if 
more firms are going to use the language, then it becomes more enticing 
for newbies wanting to dust-off their CVs learning that tech, and so on.
Moreover, think of the best (in the sense of bigger quantitatively) 
marketing booster Lua has nowadays, people modding games using embedded 
Lua. They are kiddies or youngsters that really don't care about Lua in 
itself, mostly. They like modding their game platform and they learn Lua 
in the process. Will they become developers? Maybe, but many of them 
probably are not interested in buying a book to do that, now.
Although you can gather the info if you know a fair amount of C and you 
are a decent developer (in any language, I mean), youngsters or newbies 
that don't know C and/or can't browse the Internet for tech docs are out 
of the game.
Usually lua-l friendliness compensated for that, but you must be willing 
to jump through hoops a good deal anyway.
It's no surprise that lately the only new users I see on lua-l seems to 
be expert programmers. I don't see many new users that describe 
themselves as newbie developers or students (I hope I'm wrong).
And mind you, I hear ever more people wanting to embed Python nowadays!
The very few cases in which I was in the position of suggesting Lua, I was told something like "I/we/my colleague already use Python for something else, so it will be easier to use after we embed it." That makes me fear that Lua is losing terrain even on one of its BEST selling point!
</rant>

Anyway, sorry for the rant! :-)

Cheers!

  -spc


-- Lorenzo Donati