[Top][All Lists]

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

Re: [Bug-apl] Error handling and IO

From: Juergen Sauermann
Subject: Re: [Bug-apl] Error handling and IO
Date: Wed, 20 Apr 2016 12:54:00 +0200
User-agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Thunderbird/31.4.0

Hi Elias,

that construct is already in place, called an EOC (end-of-context) handler .

However, using EOC handlers appears to be easy, but using them properly is
extremely difficult, because they require very detailed knowledge of the internals

For example, if your native function is used together with an operator (typically the
EACH or the POWER operator) then every iteration of the operator may construct
a new )SI frame (and call its EOC handlers when finished, except for the last iteration).
And you there could be have multiple EOC handlers in the same )SI frame.

There is a fairly large number of previous trouble reports that were caused by improper
use of EOC handlers (by myself). EOC handlers are one of the two most difficult (read:
error-prone) areas in GNU APL (the other one being output formatting).

Besides the trouble that EOC handlers cause, it is not really clear to me under which
circumstances it would make sense to defer the handling of an error until the )SI stack
is popped (as opposed to handling it right away).

If all you need is a APL function cleanup that is called after some other function foo
has finished (with an error or not) then you could do something like:

      cleanup ⊢ '' ⎕EA 'foo'

This is somewhat ugly because you do it above foo rather than inside foo, but it is beautiful
when compared to an EOC solution

/// Jürgen

On 04/20/2016 08:31 AM, Elias Mårtenson wrote:

Do you think it would be possible to implement a "finally" construct for native libraries? Basically, what I'm asking for is the ability to register a callback with a specific stack frame that is called when that frame is unrolled.


On 14 Apr 2016 01:51, "Juergen Sauermann" <address@hidden> wrote:
Hi Kacper et al,

I understand. But I would say that using ⎕EA as you describe is exactly how
cleanup should be done. I see ⎕EA not like (as the name may suggest) a means of
trying different paths until one succeeds like in:

'try_A' ⎕EA 'try_B' ⎕EA 'try_C' ...

but rather as:

'cleanup_failed_B' ⎕EA 'try_B'

I also don;t see a good way of introducing a defer function without introducing
a dubious APL syntax extension that would be difficult to read for people not
knowing the extended syntax. For the sake of compatibility, such things should,
IMHO, be avoided.

/// Jürgen

On 04/12/2016 02:10 AM, Kacper Gutowski wrote:
If I understand correctly, Elias wants to have something that would
ensure that every file opened is eventually closed (only more general so
it can be applied to any external resources not only files).  That is in
a code similar to the following, to ensure the line 3 is always run even
if there's an error in FUN.

[1] FD←⎕FIO[3]STH
[2] FUN FD
[3] ⎕FIO[4]FD

This can be ensured by wrapping FUN call with ⎕EA or ⎕EC.  They return
to the caller instead of suspending execution if error happens and this
is correct and expected behaviour.  But the intention is to have the
file closed, not making the function unsuspendable, so this would be
a side effect of the solution of using ⎕EA rather than the intended
behaviour.  But this doesn't mean there's anything wrong with ⎕EA or
⎕EC, of course.

My understanding is that requested is some way to associate some kind of
clean up code with )SI entry that would be run upon that entry being
cleared from )SI regardless of how that happens.

The way I imagine it, it could look like this (using an imaginary
function ‘defer’ with a name borrowed from Golang; not an actual

      ∇ FOO
[1] FD←⎕FIO[3]STH
[2] defer '⎕FIO[4]FD'
[3] FUN FD
[4] other stuff ∇

      ⎕FX 'FUN F' '1+'

FUN[1]  1+
      ⍝ here situation can be examined
F   FD
FUN[1]  1+
⋆  FOO
      ⍝ here ⎕FIO[4]FD is executed


reply via email to

[Prev in Thread] Current Thread [Next in Thread]