about 'fail'

classic Classic list List threaded Threaded
27 messages Options
12
Reply | Threaded
Open this post in threaded view
|

about 'fail'

Phil Leblanc
1)  I understand that 'fail' is not a literal value (such as 'true'),
and not a reserved word.  Is it correct to say It is a variable name
which happens to be undefined, and so evaluates to nil?

2) Does the Lua team encourage C extension developers to use
luaL_pushfail(L) instead of lua_pushnil(L)?  if yes, maybe
luaL_pushfail should be documented in the manual, section 5.

3) Do you encourage Lua library developers to update their libraries
and start using  use the idiom "return fail, msg" in case of error
(instead of "return nil, msg")?

If yes, I would recommend a big warning somewhere in the manual
(where?) and also in every "new style" library documentation:  If such
a library is used in a program which happens to define 'fail' as a
global variable, it may be an issue.

An option would be for library developers to systematically add a
"local fail = nil" at the beginning of their modules (or "assert(not
fail)")

4. As Roberto explained:
>  "So, the motivation for the change is to move our minds from the concept that errors return (nil,msg) to the concept that errors return (falsy,msg). Maybe one day in the distant future we might change that falsy to false instead of nil."

So would you encourage developers to start using "return false, msg"
in case of error instead of return nil, msg ?

TIA,

Phil

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Tim Hill


> On Oct 5, 2019, at 1:35 PM, Phil Leblanc <[hidden email]> wrote:
>
> 1)  I understand that 'fail' is not a literal value (such as 'true'),
> and not a reserved word.  Is it correct to say It is a variable name
> which happens to be undefined, and so evaluates to nil?
>
> 2) Does the Lua team encourage C extension developers to use
> luaL_pushfail(L) instead of lua_pushnil(L)?  if yes, maybe
> luaL_pushfail should be documented in the manual, section 5.
>
> 3) Do you encourage Lua library developers to update their libraries
> and start using  use the idiom "return fail, msg" in case of error
> (instead of "return nil, msg")?
>
> If yes, I would recommend a big warning somewhere in the manual
> (where?) and also in every "new style" library documentation:  If such
> a library is used in a program which happens to define 'fail' as a
> global variable, it may be an issue.
>
> An option would be for library developers to systematically add a
> "local fail = nil" at the beginning of their modules (or "assert(not
> fail)")
>
> 4. As Roberto explained:
>> "So, the motivation for the change is to move our minds from the concept that errors return (nil,msg) to the concept that errors return (falsy,msg). Maybe one day in the distant future we might change that falsy to false instead of nil."
>
> So would you encourage developers to start using "return false, msg"
> in case of error instead of return nil, msg ?
>
> TIA,
>
> Phil
>

This has been discussed before, with the usual back-and-forth about having a unique value that is falsy but is different from nil and false (which both have non-fail semantics in many cases). Roberto hasn’t been keen on such a thing (he shot me down pretty thoroughly lol), but I still think it’s a hole in the language.

—Tim


Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Egor Skriptunoff-2
In reply to this post by Phil Leblanc
On Sat, Oct 5, 2019 at 11:36 PM Phil Leblanc wrote:
So would you encourage developers to start using "return false, msg"
in case of error instead of return nil, msg ?

No!
The manual says that in Lua 5.4 "fail" equals to nil.
So, other people's code might rely on it when using your module.


"fail" might switch its value in some future Lua version.
To survive this event, you will have to do the following:

1) everywhere in your existing Lua code, when checking the status, you must replace
if status == nil then
with
if not status then

2) everywhere in your existing C code, when checking the status, you must replace
lua_isnil
with
!lua_toboolean

3) everywhere in your existing Lua code, where standard library functions were reimplemented, when returning the status, you must replace
return nil, msg
with
return false, msg

4) everywhere in your existing C code, where standard library functions were reimplemented, when preparing status to be returned, you must replace
lua_pushnil
to
lua_pushboolean


You can apply changes #1 and #2 right now without deferring to the actual switching of "fail".
You can not apply changes #3 and #4 right now.

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Roberto Ierusalimschy
> On Sat, Oct 5, 2019 at 11:36 PM Phil Leblanc wrote:
>
> > So would you encourage developers to start using "return false, msg"
> > in case of error instead of return nil, msg ?
> >
>
> No!
> The manual says that in Lua 5.4 "fail" equals to nil.
> So, other people's code might rely on it when using your module.

The manual says that "Currently, @fail is equal to @nil, but that may
change in future versions."

For old libraries and functions, changing nil to false may cause
incompatibilites. New libraries and functions, however, are free
to use false instead of nil. The new function 'debug.setcstacklimit'
in the standard library does that.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Oliver Kroth
I would like to stay with that a function on error returns something
that evaluates to nil, not false.

there are function returning a boolean value, which in case of failure
need to return a third, distinct value. nil.
Think of a function that for a file name returns whether it is a
directory or not.

--
Oliver Kroth
> For old libraries and functions, changing nil to false may cause
> incompatibilites. New libraries and functions, however, are free
> to use false instead of nil. The new function 'debug.setcstacklimit'
> in the standard library does that.
>
> -- Roberto
>


Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Egor Skriptunoff-2
On Mon, Oct 7, 2019 at 7:01 PM Oliver Kroth  wrote:
there are function returning a boolean value, which in case of failure
need to return a third, distinct value. nil.
Think of a function that for a file name returns whether it is a
directory or not.


In this situation you would better return
- filename (a string, the function's parameter) if it is a directory
- fail, 'Not a directory' if it is a file
- fail, err_mes if some error occurred

A nice one-liner:
set_current_dir(assert(is_a_directory(filename)))
This short one-liner would be impossible if the function is_a_directory(filename) returns true/false


I would like to stay with that a function on error returns something
that evaluates to nil, not false.
 
A similar thought:
Currently, string.match returns a tuple of captures which may be strings and numbers.
Theoretically, it was possible to add to Lua patterns a new kind of captures having boolean values.
After switching to "fail == false" this possibility will be closed forever.


Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Andrew Gierth
In reply to this post by Oliver Kroth
>>>>> "Oliver" == Oliver Kroth <[hidden email]> writes:

 Oliver> there are function returning a boolean value, which in case of
 Oliver> failure need to return a third, distinct value. nil. Think of a
 Oliver> function that for a file name returns whether it is a directory
 Oliver> or not.

Ah yes, the classic "true", "false", "FileNotFound"

https://thedailywtf.com/articles/What_Is_Truth_0x3f_

--
Andrew.

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Phil Leblanc
Roberto>  For old libraries and functions, changing nil to false may cause
incompatibilites. New libraries and functions, however, are free
to use false instead of nil. The new function 'debug.setcstacklimit'
in the standard library does that.

Of course no change for existing functions; my question was what is
your suggestion for new code. I guess the 'debug.setcstacklimit'
example is the answer. Thanks.


 Oliver> there are function returning a boolean value, which in case of
 Oliver> failure need to return a third, distinct value. nil. Think of a
 Oliver> function that for a file name returns whether it is a directory
 Oliver> or not.

The idiom being "return false, msg" in case of error,  I guess it
could be used that way:

  local isdir, msg = is_directory(fpath)
  if  isdir and msg then do_error_things(msg)
  elseif  isdir then do_directory_things()
  else fo file_things()
  end

testing for error could  just be testing on msg instead of testing
equality to nil.

Andrew> Ah yes, the classic "true", "false", "FileNotFound"
> https://thedailywtf.com/articles/What_Is_Truth_0x3f_

:-)

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Roberto Ierusalimschy
In reply to this post by Egor Skriptunoff-2
> Currently, string.match returns a tuple of captures which may be strings
> and numbers.
> Theoretically, it was possible to add to Lua patterns a new kind of
> captures having boolean values.
> After switching to "fail == false" this possibility will be closed forever.

Theoretically, it was possible to add to Lua patterns a new kind of
captures having nil values, too. (LPeg has both.) This possibility is
already closed forever.

Any function where you have to distinguish between nil and false in the
return value seems a very bad idea. The standard library always avoided
that, and will continue to do so.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Soni "They/Them" L.


On 2019-10-08 9:15 a.m., Roberto Ierusalimschy wrote:

> > Currently, string.match returns a tuple of captures which may be strings
> > and numbers.
> > Theoretically, it was possible to add to Lua patterns a new kind of
> > captures having boolean values.
> > After switching to "fail == false" this possibility will be closed forever.
>
> Theoretically, it was possible to add to Lua patterns a new kind of
> captures having nil values, too. (LPeg has both.) This possibility is
> already closed forever.
>
> Any function where you have to distinguish between nil and false in the
> return value seems a very bad idea. The standard library always avoided
> that, and will continue to do so.
>
> -- Roberto
>
next({[false]=true})?

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Chris Smith
In reply to this post by Roberto Ierusalimschy

> On 8 Oct 2019, at 13:15, Roberto Ierusalimschy <[hidden email]> wrote:
>
> Any function where you have to distinguish between nil and false in the
> return value seems a very bad idea. The standard library always avoided
> that, and will continue to do so.


Really?  I use this to validate config entries: entry, err = get_value(‘my_bool’).  Entry is either true, false or nil if the user didn’t specify a value or gave an erroneous value.  Why is that a bad idea?

Chris

Chris Smith <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Tomás Guisasola
Hi Chris

I would say that functions that return booleans might not fail...

Regards,
Tomás

Em ter, 8 de out de 2019 às 09:49, Chris Smith
<[hidden email]> escreveu:

>
>
> > On 8 Oct 2019, at 13:15, Roberto Ierusalimschy <[hidden email]> wrote:
> >
> > Any function where you have to distinguish between nil and false in the
> > return value seems a very bad idea. The standard library always avoided
> > that, and will continue to do so.
>
>
> Really?  I use this to validate config entries: entry, err = get_value(‘my_bool’).  Entry is either true, false or nil if the user didn’t specify a value or gave an erroneous value.  Why is that a bad idea?
>
> Chris
> —
> Chris Smith <[hidden email]>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Roberto Ierusalimschy
In reply to this post by Soni "They/Them" L.
> >Any function where you have to distinguish between nil and false in the
> >return value seems a very bad idea. The standard library always avoided
> >that, and will continue to do so.
> >
> >-- Roberto
> >
> next({[false]=true})?

You are right. This function is in Lua since version 1.0. It probably
would have a different API today. (It also spoiled the generic for.)

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Soni "They/Them" L.


On 2019-10-08 10:04 a.m., Roberto Ierusalimschy wrote:

> > >Any function where you have to distinguish between nil and false in the
> > >return value seems a very bad idea. The standard library always avoided
> > >that, and will continue to do so.
> > >
> > >-- Roberto
> > >
> > next({[false]=true})?
>
> You are right. This function is in Lua since version 1.0. It probably
> would have a different API today. (It also spoiled the generic for.)
>
> -- Roberto
>

Would it be time to start looking to a Lua 6?

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

D Burgess-3
> Really?  I use this to validate config entries: entry, err = get_value(‘my_bool’).  Entry is either true, false or nil if the user didn’t specify a value or gave an erroneous value.  Why is that a bad idea?

I have encountered this frequently in Lua code. i.e. nil representing
"no value"
Also common is set_something(nil) meaning to use the default.

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Ahmed Charles
In reply to this post by Roberto Ierusalimschy
On Oct 8, 2019, at 6:04 AM, Roberto Ierusalimschy <[hidden email]> wrote:

>>> Any function where you have to distinguish between nil and false in the
>>> return value seems a very bad idea. The standard library always avoided
>>> that, and will continue to do so.
>>>
>>> -- Roberto
>>>
>> next({[false]=true})?
>
> You are right. This function is in Lua since version 1.0. It probably
> would have a different API today. (It also spoiled the generic for.)
>
> -- Roberto

What api would you prefer for next? And how did its current api spoil generic for? Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Jonathan Goble
On Wed, Oct 9, 2019 at 5:58 PM Ahmed Charles <[hidden email]> wrote:

>
> On Oct 8, 2019, at 6:04 AM, Roberto Ierusalimschy <[hidden email]> wrote:
>
> >>> Any function where you have to distinguish between nil and false in the
> >>> return value seems a very bad idea. The standard library always avoided
> >>> that, and will continue to do so.
> >>>
> >>> -- Roberto
> >>>
> >> next({[false]=true})?
> >
> > You are right. This function is in Lua since version 1.0. It probably
> > would have a different API today. (It also spoiled the generic for.)
> >
> > -- Roberto
>
> What api would you prefer for next? And how did its current api spoil generic for? Thanks.

My best guess would be the inability to iterate through and past nil.
The obvious solution is signaling the end with an exception like in
Python instead of a potentially valid and useful object like nil, but
of course proper exceptions are not so easy to implement.

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Soni "They/Them" L.


On 2019-10-09 7:51 p.m., Jonathan Goble wrote:

> On Wed, Oct 9, 2019 at 5:58 PM Ahmed Charles <[hidden email]> wrote:
> >
> > On Oct 8, 2019, at 6:04 AM, Roberto Ierusalimschy <[hidden email]> wrote:
> >
> > >>> Any function where you have to distinguish between nil and false in the
> > >>> return value seems a very bad idea. The standard library always avoided
> > >>> that, and will continue to do so.
> > >>>
> > >>> -- Roberto
> > >>>
> > >> next({[false]=true})?
> > >
> > > You are right. This function is in Lua since version 1.0. It probably
> > > would have a different API today. (It also spoiled the generic for.)
> > >
> > > -- Roberto
> >
> > What api would you prefer for next? And how did its current api spoil generic for? Thanks.
>
> My best guess would be the inability to iterate through and past nil.
> The obvious solution is signaling the end with an exception like in
> Python instead of a potentially valid and useful object like nil, but
> of course proper exceptions are not so easy to implement.
>
if select('#',...) was built into the language instead of being a C-ism
(as in, something that leaks C API details) then for loops could've just
stopped on no value.

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Scott Morgan
On 10/10/2019 00:03, Soni "They/Them" L. wrote:
>
> if select('#',...) was built into the language instead of being a C-ism
> (as in, something that leaks C API details) then for loops could've just
> stopped on no value.
>

Kinda related, and Just spitballing here: Been wondering if tuples
should be fully supported in Lua. We already have the ... operator, that
kinda acts like it, why not go all in?

 > local tup = make_tuple('a', nil, 3)  -- imagine better syntax here

 > =tup[1]
 a

 >#tup
 3

 > local x,y,z = tup
 > =x,y,z
 a    nil   3

 > local tup_copy = return tup
 > =#tup_copy
 3

 >tup[2] = 'foo'
 * Error: Tuples are read only

 > local pi = make_tuple(3.1425)  -- consts ;)

 > for x in tup do print(x); end
 a
 nil
 3

Maybe do car and cdr functions too :)

Scott

Reply | Threaded
Open this post in threaded view
|

Re: about 'fail'

Luiz Henrique de Figueiredo
> Been wondering if tuples should be fully supported in Lua.
> local tup = make_tuple('a', nil, 3)  -- imagine better syntax here

This can already be done via a library. There are some around.

12