new thought experiment: what would you add to Lua ?

classic Classic list List threaded Threaded
45 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Re: new thought experiment: what would you add to Lua ?

Frank Kastenholz-2


Like io.popen?

(FWIW - depending on where you port/install Lua, there are a bunch of other things you may not have ... but I digress)

On Sep 15, 2018, at 2:44 PM, Andrew Gierth <[hidden email]> wrote:

>>>>>> "Frank" == Frank Kastenholz <[hidden email]> writes:
>
> Frank> os.setenv, as a counterpart to os.getenv?
>
> There's a reason for that not to exist - getenv() is part of ISO C, but
> there is no standard C function to _set_ environment vars, because that
> is platform-dependent territory.
>
> --
> Andrew.
>


Reply | Threaded
Open this post in threaded view
|

Re: new thought experiment: what would you add to Lua ?

Sean Conner
In reply to this post by Frank Kastenholz-2
It was thus said that the Great Frank Kastenholz once stated:
>
> os.setenv, as a counterpart to os.getenv?

  setenv() is not a standard C function (it is in POSIX).  Lua only uses
standard C functions, thus its ommission.

  One oddly lacking function is localeconv().  We have os.setlocale() but
not os.localeconv().  

> I also like the idea of a switch statement (maybe taking bash’s notion of
> patterns in the cases :-)

  You could always use a table for this.

> But none really are critical (to me)

  Same here.

  -spc


Reply | Threaded
Open this post in threaded view
|

AW: new thought experiment: what would you add to Lua ?

michaelflad
In reply to this post by Luiz Henrique de Figueiredo
Thanks for the link - may thoughts were more along an integrated solution as everything
else can be uncomfortable to use.

That said, I haven't thought about the most obvious solution. I just wrote a package loader
that removes all the lines with assertions. It's just a tiny hack but works like a charm, thanks
to the flexibility of Lua.
Of course I'll have to change this into a real preprocessing step for releases that might
use precompiled Lua code but that's not an issue.
 

> -----Ursprüngliche Nachricht-----
> Von: [hidden email] <[hidden email]> Im Auftrag
> von Luiz Henrique de Figueiredo
> Gesendet: Samstag, 15. September 2018 11:42
> An: Lua mailing list <[hidden email]>
> Betreff: Re: new thought experiment: what would you add to Lua ?
>
> > Especially during optimization, as I rely on some hairy edge cases, I
> > added assertions all over the place, but at some point it's just
> > required to remove/comment them all out as it's simply not an option
> > to not remove them
>
> One of the examples in my ltokenp, a token processor for Lua, is for
> removing assertions:
> http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#ltokenp


Reply | Threaded
Open this post in threaded view
|

Re: new thought experiment: what would you add to Lua ?

Alysson Cunha
In reply to this post by Sam Putman
That "fake" piece of code is so ugly, which makes difficult to others programmers understand your code. 

Besides, it does not handle "finally" correctly because, in case of "finally  execution due error, the error must be raised again

Em Sáb, 15 de set de 2018 10:40, Sam Putman <[hidden email]> escreveu:


On Sat, Sep 15, 2018 at 3:00 PM Peter Hickman <[hidden email]> wrote:
On Sat, 15 Sep 2018 at 11:58, Alysson Cunha <[hidden email]> wrote:
try-catch and try-finally language sugars for pcall to simplify error handling

This is the one thing that would make things much easier for me. I know we should wrap things in pcall incase they fail but there are so many things that *could* fail the resulting code becomes unreadable very quickly

A few judicious try-catch blocks can provide much robustness without obscuring the code. I tend to write code in a more iterative fashion with a few large scoped try-catch blocks (or begin-rescue-end as I'm actually a Ruby programmer) until the part of the code that is fragile comes to light


This can be adequately faked:

-- try
local success, err = pcall(function()
    -- your chunk goes here
end)
-- catch
if not success then
   -- do stuff with err
end
-- finally



 
I understand that this may be more a case of "trying to write Ruby in Lua" but I miss this more I miss OOP. I have no problem with Lua not being an OOP language, it's easy to adapt to. But catching errors seems to require chopping up the code in unnatural ways so that it can be stuffed into a function that can be pcalled

Otherwise it's still a wonderful language

Reply | Threaded
Open this post in threaded view
|

Re: new thought experiment: what would you add to Lua ?

Sam Putman


On Sun, Sep 16, 2018 at 3:14 PM Alysson Cunha <[hidden email]> wrote:
That "fake" piece of code is so ugly, which makes difficult to others programmers understand your code. 

Besides, it does not handle "finally" correctly because, in case of "finally  execution due error, the error must be raised again



A matter of taste, I think it's less ugly than top-posting on a mailing list, but ymmv.

If you absolutely must have a finally block execute, let me share something I thought was too obvious the first time.

-- try
local success, err = pcall(function()
    -- your chunk goes here
end)
-- catch
if not success then pcall(function()
   -- do stuff with err
     end)
end
-- finally 
Reply | Threaded
Open this post in threaded view
|

Re: new thought experiment: what would you add to Lua ?

Sean Conner
In reply to this post by Alysson Cunha
It was thus said that the Great Alysson Cunha once stated:
> That "fake" piece of code is so ugly, which makes difficult to others
> programmers understand your code.

  It seems pretty understandable to me, but then I'm not a fan of OOP.

  At work, I have to work with code that was described by its programmer as
"boring, plain, straightforward code that uses no tricks." I can't
understand it *at all*.  And of course, the reverse is true---my boring,
plain, straightforward code that uses no tricks is very hard for the other
programmer to understand.

> Besides, it does not handle "finally" correctly because, in case of
> "finally  execution due error, the error must be raised again

  Different langauges handle exceptions differently.  Java requires checked
exceptions (a function must declare it throws an exception, even if it
doesn't do so directly [1]) where as C++ does not.  If you are used to
checked excpetions, then C++ (and even this Lua example) would not work for
you.

  I am also not a fan of exceptions as currently implemented in every
language [2].

  -spc (That's not to say I haven't used exception-like stuff, but only
        in very certain situations [4]).

[1] Which I found extremely annoying.  I can understand the rational for
        it but that doesn't mean it's a good idea.

[2] Personally, I don't think exceptions should exist as a concept in
        user code at all.  If a program reeives a seg fault (a perfect
        example of an exception) then the program is borked---is is trying
        to reference memory that is not mapped into its memory space and
        trying to recover might not be the best approach (or even possible,
        depending upon where it happened).

        Other possible exceptional events, like division by 0, invalid
        opcode, memory error [3], likewise means the program is operating
        incorrectly and any attempts for the program to save itself (or
        ignore the error) is in vain.

        Errors that are usually signaled via exceptions (out of bounds,
        can't open a file, network connection dropped, window changed size,
        etc) are a normal occurance and may or may not indicate an error
        (out of bounds, if unexpected, yes---perhaps the code was probing in
        which case, no; can't open a file, maybe it doesn't exist and that's
        okay at that point in time).

        I know I'm probably in the minority with this viewpoint.

[3] The original IBM PC mapped memory errors to the NMI line and would
        basically stop all processing entirely, in the ground that if memory
        is corrupt, there's is no point in going any further---even the OS
        might be borked.

[4] Parsing text.  I have found it much nicer to just skip back to the
        top of the main parsing loop instead of trying to bubble up errors
        through the call stack.  But in this case, it's not an "exception"
        but more of a "controlled jump back to where I can return an error
        to the calling code".  Why not propagate the "exception" back to the
        calling code?  It depends upon the language and how complex (or
        nasty) the code would be to catch the controlled jump.

Reply | Threaded
Open this post in threaded view
|

Re: new thought experiment: what would you add to Lua ?

Sean Conner
It was thus said that the Great Sean Conner once stated:
>
> [2] Personally, I don't think exceptions should exist as a concept in
                                                   ^NOT

> user code at all.  If a program reeives a seg fault (a perfect
> example of an exception) then the program is borked---is is trying
> to reference memory that is not mapped into its memory space and
> trying to recover might not be the best approach (or even possible,
> depending upon where it happened).

  Oops.

  -spc

Reply | Threaded
Open this post in threaded view
|

Exception handling (was Re: ...add to Lua...)

Dirk Laurie-2
Op Ma., 17 Sep. 2018 om 00:08 het Sean Conner <[hidden email]> geskryf:

>
> It was thus said that the Great Sean Conner once stated:
> >
> > [2]   Personally, I don't think exceptions should exist as a concept in
>                                                    ^NOT
>
> >       user code at all.  If a program reeives a seg fault (a perfect
> >       example of an exception) then the program is borked---is is trying
> >       to reference memory that is not mapped into its memory space and
> >       trying to recover might not be the best approach (or even possible,
> >       depending upon where it happened).
>
>   Oops.

That single ^NOT, appearing in a non-monospaced font, correcting a
sentence starting "Personally" (which usually means that, in the
opinion of the author, a non-PC point of view will follow) makes it
totally impossible to figure out what you are trying to convey.

Do you basically agree that

(a) languages usually run from an interpreter or a host program (as
Lua is) should offer (as Lua does) three abnormal exits from a
program:
(i) to the previous level of execution [1]
(ii) to the host [2]
(iii) to the system [3]

(b) that the previous level should be allowed to intercept an exit to
the host [4]

c) that this degree of flexibilty is in fact quite rare in other
languages, even (if not especially) those with "try..except"
mechaniisms?

-- Dirk

[1] In Lua, by way of type and number of return values, especially
"false, message"'
[2] In Lua, by way of error())
[3] In Lua, by way of os.exit()
[4] In Lua, by way of pcall()

Reply | Threaded
Open this post in threaded view
|

Re: Exception handling (was Re: ...add to Lua...)

Sean Conner
It was thus said that the Great Dirk Laurie once stated:
> Op Ma., 17 Sep. 2018 om 00:08 het Sean Conner <[hidden email]> geskryf:
> >
> > It was thus said that the Great Sean Conner once stated:
> > >
> > > [2]   Personally, I don't think exceptions should exist as a concept in
> >                                                    ^NOT


> > >       user code at all.  If a program reeives a seg fault (a perfect
> > >       example of an exception) then the program is borked---is is trying
> > >       to reference memory that is not mapped into its memory space and
> > >       trying to recover might not be the best approach (or even possible,
> > >       depending upon where it happened).
> >
> >   Oops.
>
> That single ^NOT, appearing in a non-monospaced font, correcting a
> sentence starting "Personally" (which usually means that, in the
> opinion of the author, a non-PC point of view will follow) makes it
> totally impossible to figure out what you are trying to convey.

  I messed that up (I can't read today---it was fine as it was originally).

  Basically, exceptions should not exist as a concept in user code.  This
gets into error handling in general.  There only exists two ways to handle
errors:

        1) it is handled by the routine itself
        2) it is passed off to another routine

  Going into further detail:

        1) it is handled by the routine itself
          a) no check is performed at all [5]
          b) the error condition is noticed but ignored

        2) it is passed off to another routine
          a) by passing an error indication to the caller
          b) by calling code to handle the error

Exceptions fall under 2b) calling code to handle the error.  Yes, I contend
that most (if not all) exceptions are (expensive) calls to some other piece
of code.  If it's a hardware exception (like a segfault or divide-by-0) it's
an expensive call into the kernel; for a C++ or Java like exception, it's
probably to code that walks back up the call chain looking for a suitable
handler, possibly calling destructors (if in C++) along the way.  

  The main reason I dislike exceptions is they are overused (much like OOP
is overused [6]).  Furthermore, they are a form of dynamic GOTO (via that
expensive call) that makes it very hard to figure out flow control.  You had
Java with checked exceptions, but that made code exceedingly tedious to
program so everybody derived from the one non-checked exception
available---RunTimeException.  C++ never did the checked exceptions (so
there's that) but you still have issue with where did the execution go?

  Now, on to your questions ...

> Do you basically agree that
>
> (a) languages usually run from an interpreter or a host program (as
> Lua is) should offer (as Lua does) three abnormal exits from a
> program:

  What do you mean by "program?" [8]

> (i) to the previous level of execution [1]

  So here "program" is "function"?

> (ii) to the host [2]

  What do you mean by "host?"  Because my definition is the same as
"system", which you list below.

> (iii) to the system [3]
>
> (b) that the previous level should be allowed to intercept an exit to
> the host [4]
>
> c) that this degree of flexibilty is in fact quite rare in other
> languages, even (if not especially) those with "try..except"
> mechaniisms?

  There's LISP, which goes even futher with conditions.

> -- Dirk
>
> [1] In Lua, by way of type and number of return values, especially
> "false, message"'
> [2] In Lua, by way of error())
> [3] In Lua, by way of os.exit()
> [4] In Lua, by way of pcall()

  I'm not sure I follow you line of thought here.  (i) is your typical

                if some_error_condition then
                  return some_error_indication
                end

  Your (ii) and (b) are two sides of the same coin, as pcall() can
"intercept" error() (basically, pcall() is a catch to error()'s throw).  But
my main thrust against exceptions is really your case (b)---if you catch a
Lua syntax error via pcall(), what can you realistically do in that case [9]?
Not much---it requires user intervention to fix the error.  The same for
trying to divide by 0, or anything else that causes Lua to abort execution
of Lua code.

  So I'm having a hard time agreeing or disagreeing with your statement.

  -spc (If it helps, I'm in the "fail fast" category of programmer ... )

[5] Back in college, I found myself with a problem where I could not
        figure out how to handle an error condition---the screen won't be
        seen, the disk is full, and the printer is off-line, how do you
        report the error?  I asked one of the professors who answer---"If
        you don't know how to handle the error, don't check for it." I was
        horrified by the answer, but time has shown he was correct.

[6] Alan Kay is upset at us (as an industry) for failing to read his
        mind with respect to object oriented programming.  He didn't
        actually mean objects ala C++ or Java, but small simple programs
        that process messages handed to them.

        To be fair to us, he didn't explain himself very well when Smalltalk
        was released and we ended up with a generation of programmers trying
        to figure out if a square is a subclass of a vehicle or is the
        vehicle a subclass of a mammal [7].

        The followup generation now talk about dependency factory factories
        and raviola code---the OOP version of spaghetti code.

[7] A joke.  Most OOP is taught using shapes, vehicles or animals.  All
        horrible examples for OOP.

[8] I have a definition in mind, but it might not be your definition.

[9] I wrote about it a bit here:

                http://boston.conman.org/2009/12/01.2

        (near the bottom)---I classified four categories for errors, along
        with three ways of handling them, but I've thought hard about that
        since then and modified my position somewhat (two two ways of
        handling errors).


Reply | Threaded
Open this post in threaded view
|

Re: Exception handling (was Re: ...add to Lua...)

pocomane
On Mon, Sep 17, 2018 at 9:36 AM Sean Conner <[hidden email]> wrote:
> "intercept" error() (basically, pcall() is a catch to error()'s throw).  But
> my main thrust against exceptions is really your case (b)---if you catch a
> Lua syntax error via pcall(), what can you realistically do in that case [9]?

If your system is radiation critical, probably you have a redundant
cache for your code. If one fails, you can at least try to load the
second one.

However, I 100% agree that OOP and Exceptions are commonly abused/misused.

Reply | Threaded
Open this post in threaded view
|

Re: Exception handling (was Re: ...add to Lua...)

Dirk Laurie-2
In reply to this post by Sean Conner
Op Ma., 17 Sep. 2018 om 09:36 het Sean Conner <[hidden email]> geskryf:
>
> It was thus said that the Great Dirk Laurie once state
> >
> > That single ^NOT, appearing in a non-monospaced font, correcting a
> > sentence starting "Personally" (which usually means that, in the
> > opinion of the author, a non-PC point of view will follow) makes it
> > totally impossible to figure out what you are trying to convey.
>
>   I messed that up (I can't read today---it was fine as it was originally).

I'm not quoting your good, clear explanation, but would urge readers
whose mail clients are good enough to reread it.

>   Now, on to your questions ...
>
> > Do you basically agree that
> >
> > (a) languages usually run from an interpreter or a host program (as
> > Lua is) should offer (as Lua does) three abnormal exits from a
> > program:
>
>   What do you mean by "program?" [8]
...
> What do you mean by "host?"

As used the Lua manual: "Lua ... works embedded in a host client,
called the embedding program or simply the host."

> Because my definition is the same as "system", which you list below.

I was hoping that my footnotes, giving the corresponding Lua
functions, would make that clear.

> > [1] In Lua, by way of type and number of return values, especially
> > "false, message"'
> > [2] In Lua, by way of error())
> > [3] In Lua, by way of os.exit()
> > [4] In Lua, by way of pcall()

But let's try again.

Level 0    Operating system (whether shell or GUI)
Level 1    Invokes a command or starts an application called "lua",
"python", "perl", "ruby", "js", "apl", "love", "luatex" etc.
Level 2    which invokes code written in a 'scripting" language
Level 3    which calls a function
Level 4    which calls a function
...
Level n    which encounters a condition that makes it impossible to go
on as normal.

Now from level n, Lua code can say: return to level  0 (bypassing all
finalizers not regestered at that level) or return to level 1
(allowing various sorts of recovery) or drop down to level n-1
(passing the buck). In addidition, Level n-1 may disallow a direct
return to Level 1.

The questions to agree or disagree on are:

(a) All languages that involve at least Levels 0,1,2 should offer all
those options.
(b) Very few except Lua actually offer that.

> [9]     I wrote about it a bit here:
>
>                 http://boston.conman.org/2009/12/01.2
>
>         (near the bottom)---I classified four categories for errors, along
>         with three ways of handling them, but I've thought hard about that
>         since then and modified my position somewhat (two two ways of
>         handling errors).

I think I understand both that post and your explanation of the 2x2
position, but it will require a chain of deductions to move from there
to answers to my questions, and I don't wish to second-guess you :-)

-- Dirk

Reply | Threaded
Open this post in threaded view
|

Re: Exception handling (was Re: ...add to Lua...)

Sean Conner
It was thus said that the Great Dirk Laurie once stated:

> Op Ma., 17 Sep. 2018 om 09:36 het Sean Conner <[hidden email]> geskryf:
> >
> > It was thus said that the Great Dirk Laurie once state
>
> I was hoping that my footnotes, giving the corresponding Lua
> functions, would make that clear.
>
> > > [1] In Lua, by way of type and number of return values, especially
> > > "false, message"'
> > > [2] In Lua, by way of error())
> > > [3] In Lua, by way of os.exit()
> > > [4] In Lua, by way of pcall()
>
> But let's try again.
>
> Level 0    Operating system (whether shell or GUI)
> Level 1    Invokes a command or starts an application called "lua",
> "python", "perl", "ruby", "js", "apl", "love", "luatex" etc.
> Level 2    which invokes code written in a 'scripting" language
> Level 3    which calls a function
> Level 4    which calls a function
> ...
> Level n    which encounters a condition that makes it impossible to go
> on as normal.

  Okay.

> Now from level n, Lua code can say: return to level  0 (bypassing all
> finalizers not regestered at that level) or return to level 1
> (allowing various sorts of recovery) or drop down to level n-1
> (passing the buck). In addidition, Level n-1 may disallow a direct
> return to Level 1.

  Much more clear (at least to me).  

> The questions to agree or disagree on are:
>
> (a) All languages that involve at least Levels 0,1,2 should offer all
> those options.

  I would have to agree, if only because of my hate of Go (whose developers
patronize programmers as being too dumb to understand programming [10]).  I
may not like the mechanism but that's me, and I'm not going to force my
preferences onto other people (force my opionions?  Sure, but not my
preferences [11]).

> (b) Very few except Lua actually offer that.

  Citation needed.  Even C can do that:

        Level 0: exit()
        Level 0: _exit() -- Do not pass C finalizers.  Do not collect $200 [12]

        Level 1: via signal(), sigsetjmp() and siglongjmp()
        Level n: via setjmp(), longjmp() (or signal, sigsetjmp(),
                 siglongjmp() if you really want to be masochistic).

  I would be surprised if Python, Ruby and Perl couldn't do that as well.
LISP has more options than Lua.  And the tricks you can do in Forth are only
exceeded by the tricks you can do in assmebly.

  So here, I would disagree.

  -spc (I think Pascal doesn't allow that, but that was designed for
        teaching, not actual work ... )

[5] ... [9] : not included

[10] It would be hypocritical of me to say "don't use that" when I refuse
        to use Go because of their own "don't use that" stance with their
        own langauge.

[11] A friend of mine does tech support.  When I've gone to him for
        issues (not very often) he will immedately change settings like
        screen resolution and font size because "Well, that's what I like,
        and what I like is obviously what everybody should like." I had to
        hit him a few times with a clue-by-four to stop that rude behavior.

[12] Monopoly game reference.

Reply | Threaded
Open this post in threaded view
|

Re: new thought experiment: what would you add to Lua ?

Russell Haley
In reply to this post by Andrew Gierth


On Fri, Sep 14, 2018 at 4:00 PM Andrew Gierth <[hidden email]> wrote:
Ternary (conditional) operator. Using (x and y or z) has become an
idiom, which shows the real demand for such a feature, but the fact that
it breaks when y is false or nil makes for a lot of landmines.

Something like #... to return the number of varargs without needing to
pass them all to another function as in select('#',...).

--
Andrew.

I'm a big proponent of NIL_IN_TABLE because it would give us the ability to mimic "sequences" without holes, but most other things I would like to see are syntactic sugar:
- Safe table navigation
- adding to self using  "+="
- Ternary conditions 
 
I used to be a proponent of case statements, but the flexibility of "if else" and the consistency of a single pattern for checking values is winning me over. I know ternary conditions breaks that consistency, but it could be worth breaking for the ability to write succinct code. 

As a side remark, I've been mucking with C and the intricacies of distributing Lua for so long now, I had almost forgotten what a pleasure it is to *write* Lua. My current distraction/project (a lua minecraft sever controller) has reminded me of the elegance of the language. 

Russ
Jim
Reply | Threaded
Open this post in threaded view
|

Re: new thought experiment: what would you add to Lua ?

Jim
In reply to this post by Roberto Ierusalimschy
how about adding a "continue" statement to loops ?
(yes, i know it can be achieved with "goto")

Reply | Threaded
Open this post in threaded view
|

Re: new thought experiment: what would you add to Lua ?

Oliver Kroth


Am 18.09.2018 um 20:15 schrieb Jim:
> how about adding a "continue" statement to loops ?
> (yes, i know it can be achieved with "goto")
>
Better leave the goto than open the can of worms with directional break
and continue (break out of inner loop, continue with outer, or directly
breal out of outer loop)
The goto may be easier to understand, especially for people programming
not so often.

I also wanted to have continue, but goto continue is OK to me.
--
Oliver

Reply | Threaded
Open this post in threaded view
|

Re: new thought experiment: what would you add to Lua ?

Brandon Irizarry
Yes, I'm a beginner at Lua, and I already love "goto" with labels, as a way to control looping.

- Brandon

On Tue, Sep 18, 2018, 2:27 PM Oliver Kroth <[hidden email]> wrote:


Am 18.09.2018 um 20:15 schrieb Jim:
> how about adding a "continue" statement to loops ?
> (yes, i know it can be achieved with "goto")
>
Better leave the goto than open the can of worms with directional break
and continue (break out of inner loop, continue with outer, or directly
breal out of outer loop)
The goto may be easier to understand, especially for people programming
not so often.

I also wanted to have continue, but goto continue is OK to me.
--
Oliver

Reply | Threaded
Open this post in threaded view
|

Re: Exception handling (was Re: ...add to Lua...)

Tim Hill
In reply to this post by Sean Conner


On Sep 17, 2018, at 12:36 AM, Sean Conner <[hidden email]> wrote:

1) it is handled by the routine itself
  a) no check is performed at all [5]
  b) the error condition is noticed but ignored

1c) The error condition is corrected by the routine itself.

For example, open a file at location A, fail, try location B, succeed.

—Tim

Reply | Threaded
Open this post in threaded view
|

Re: Exception handling (was Re: ...add to Lua...)

Sean Conner
It was thus said that the Great Tim Hill once stated:
>
>
> > On Sep 17, 2018, at 12:36 AM, Sean Conner <[hidden email]> wrote:
> >
> > 1) it is handled by the routine itself
> >  a) no check is performed at all [5]
> >  b) the error condition is noticed but ignored
>
> 1c) The error condition is corrected by the routine itself.

  Thanks.  I forgot that bit.

  -spc


Reply | Threaded
Open this post in threaded view
|

Re: Exception handling (was Re: ...add to Lua...)

nobody
In reply to this post by Tim Hill
On 2018-09-18 23:24, Tim Hill wrote:

>
>> On Sep 17, 2018, at 12:36 AM, Sean Conner <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>> 1) it is handled by the routine itself
>>  a) no check is performed at all [5]
>>  b) the error condition is noticed but ignored
>
> 1c) The error condition is corrected by the routine itself.
>
> For example, open a file at location A, fail, try location B, succeed.

Oooh, that reminds me of a thing that I tried a while ago... replace
`pcall` with `hopefully`!

[tl;dr: handling exceptions vs. expectations]



The try/catch (error/pcall, return nil,err / if, ...) approach is to
describe the error, throw away (part of) the stack, then try to recover.
There may be structured error descriptions (hierarchy/tags/...) that
might be "open" / extendable, but the expectation / intended result
isn't really encoded in a structured way, which means the error handling
happens in an essentially ad-hoc manner (you spell everything out all
the time...) and is "closed" / cannot be extended.

The approach I used was to have (potentially a hierarchy of) structured
_expectations_ that have a default action and an associated list of
failure handlers (which – if reachable – is "open" / extensible). From
the user code, you call `hopefully( desc, params... )` (could also be
hidden inside some constructor) and if the action fails, that tries the
handlers in order (with the stack still intact – so this is a normal
function, no language support needed etc.). If some handler manages
to fix the problem, your code just gets the result – it doesn't even see
that there were some failures. If all handlers fail, you get a plain
exception – at which point you can generally just let it throw away the
stack (maybe after doing some cleanup), because you know there's nothing
you can do to fix it.

So this doesn't fully replace normal error handling... but it reduces
the amount. In the best case, your code looks like a "happy path"
program, with dangerous places marked `hopefully(...)`. Where you need
cleanup, that can be split fairly easily into a main/cleaning function
combo, with a generic helper function that does the pcall / ok,... split
/ if dance. (Or maybe __gc is good enough, or maybe your pcall wrapper
triggers a garbage collection to make __gc good enough, or maybe it
keeps a coarse "shadow stack" that tracks pcall levels and things to
explicitly free, or...)



Ok, so far, so boring... that may be quite nice but it's not really
worth the extra effort... right?

So... let's say you're opening files and you have a fallback directory.
No problem, just wrap the file opening stuff in a function and use that
in your code. But libraries won't... ugh. So you pre-process paths all
over the place (or write a wrapper around parts of the libraries...) Or
(if those libraries were doing the structured expectation thing) you'd
add a handler for the "readable file from path" expectation that tries
the fallback path, and now everything magically works.

Or (more generally), if you happen to know that there's a user sitting
around, why not ask them what to do? You can add a handler that asks
them whether to retry / use a different name / abort. (GUI or CLI? And
which flavor? Doesn't matter – it's your handler, do what works for
you.) If expectations are structured in a hierarchy, you could even set
a top-level fallback that may decide whether to pop up a dialog or do
nothing and let other handlers try to fix it.

If there's stuff that may temporarily fail and your code is structured
as coroutines, add a handler that yields and eventually (on resume)
retries? (A library writer can do an immediate retry, but they can't (or
shouldn't) delay (single-threaded code!) for longer, can't really assume
coroutines, can't... do anything to fix it, really. But you know your
environment, know stuff that the library writer can't assume – and that
may add a bunch of options for dealing with problems... Recall how I
said that normal exceptions are "closed" and this is "open"? See the
difference?)



Does this approach have a common name? Has anyone else tried this /
knows a place where this was used? Particularly on larger code bases:
Does it keep working... or will it go up in flames? (I haven't seen this
elsewhere yet, tried this a bunch of times on smaller experiments... It
worked fine, but it looks like getting the balance on the structure of
expectations right (over-/"under-engineering") will be tricky for larger
stuff.)

-- nobody

Reply | Threaded
Open this post in threaded view
|

Re: Exception handling (was Re: ...add to Lua...)

Sean Conner
It was thus said that the Great nobody once stated:

> If there's stuff that may temporarily fail and your code is structured
> as coroutines, add a handler that yields and eventually (on resume)
> retries? (A library writer can do an immediate retry, but they can't (or
> shouldn't) delay (single-threaded code!) for longer, can't really assume
> coroutines, can't... do anything to fix it, really. But you know your
> environment, know stuff that the library writer can't assume – and that
> may add a bunch of options for dealing with problems... Recall how I
> said that normal exceptions are "closed" and this is "open"? See the
> difference?)
>
> Does this approach have a common name?

  Lisp calls them "conditions".  

  MS-DOS used this concept and allowed a program to install a "critical
error handler"---the default one provided by MS-DOS printed out

        Not ready error reading drive A
        Abort, Retry, Ignore, Fail?

and the user could hit A, R, I or F.

> Has anyone else tried this /
> knows a place where this was used? Particularly on larger code bases:
> Does it keep working... or will it go up in flames? (I haven't seen this
> elsewhere yet, tried this a bunch of times on smaller experiments... It
> worked fine, but it looks like getting the balance on the structure of
> expectations right (over-/"under-engineering") will be tricky for larger
> stuff.)

  I did something like this for C.  It was a pain to use and I gave it up.

  -spc (It's easier to manage in Lisp because of the macro system)


123