Hi,
Now I don't want to get this mail please!
Sejal.
On Sun, Mar 24, 2013 at 1:13 PM, gambit-list-request@iro.umontreal.cawrote:
Send Gambit-list mailing list submissions to gambit-list@iro.umontreal.ca
To subscribe or unsubscribe via the World Wide Web, visit https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list or, via email, send a message with subject or body 'help' to gambit-list-request@iro.umontreal.ca
You can reach the person managing the list at gambit-list-owner@iro.umontreal.ca
When replying, please edit your Subject line so it is more specific than "Re: Contents of Gambit-list digest..."
Today's Topics:
- Re: Foreign object printers? (Marc Feeley)
- Re: Your feedback would be much appreciated re: Proposal for enabling IO errors to be reported through returning of a custom value instead of by throwing exception, through DSL with exports: ##io-error-behavior param, ##default-io-error-behavior unique value, ##last-io-error param. (Mikael)
Message: 1 Date: Sun, 24 Mar 2013 13:43:38 -0400 From: Marc Feeley feeley@iro.umontreal.ca Subject: Re: [gambit-list] Foreign object printers? To: Jason Felice jason.m.felice@gmail.com Cc: Gambit List gambit-list@iro.umontreal.ca Message-ID: 4EA356E8-06FB-477A-9E97-D932618035DB@iro.umontreal.ca Content-Type: text/plain; charset=iso-8859-1
On 2013-03-24, at 1:16 PM, Jason Felice jason.m.felice@gmail.com wrote:
Whats macro-writeenv-style and ##wr-mark about?
The style field of a writeenv indicates the style in which the object is to be written. Currently the style can be
- write (11 "abc" 22) is written as: (11 "abc" 22)
- display (11 "abc" 22) is written as: (11 abc 22)
- print (11 "abc" 22) is written as: 11abc22
- pretty-print uses indentation/line breaks for pretty printing
- mark used by #n=... notation
So the mark style is special in that it does not produce output. It is used when the readtable-sharing-allowed? flag is set:
(define (wr obj allow?)
(call-with-output-string '() (lambda (p) (output-port-readtable-set! p (readtable-sharing-allowed?-set (output-port-readtable p) allow?)) (write obj p))))
(wr (let ((x (cons 11 22))) (list x x)) #f)
"((11 . 22) (11 . 22))"
(wr (let ((x (cons 11 22))) (list x x)) #t)
"(#0=(11 . 22) #0#)"
The write/display/print/pretty-print procedures will make a first pass over the object/subobjects with style=mark. This is to gather in a table all the subobjects to write. Then, during the second pass, the #n=... notation will be used when an object has been marked more than once during the mark pass.
Marc
Message: 2 Date: Sun, 24 Mar 2013 20:12:33 +0200 From: Mikael mikael.rcv@gmail.com Subject: Re: [gambit-list] Your feedback would be much appreciated re: Proposal for enabling IO errors to be reported through returning of a custom value instead of by throwing exception, through DSL with exports: ##io-error-behavior param, ##default-io-error-behavior unique value, ##last-io-error param. To: Marc Feeley feeley@iro.umontreal.ca, gambit-list@iro.umontreal.ca Message-ID: < CACbx-M-N+uhevRW9kiY0F6P9NfqqcsGS5X1bqukqbtHChcxwyA@mail.gmail.com> Content-Type: text/plain; charset="iso-8859-1"
Hi Marc!
Ah, one thing struck me: in some cases, IO primitives don't raise an exception on error but instead return a special value, I think it's #!eof always.
This would not transform to returning #f by a with-exception-handler wrapper, but it could with a port specific flag |io-error| or |eof-value| or |treat-eof-as-error|.
Do you have any thoughts on the previous email on with-exception-handler and IO error semantics yet?
Of course there's time though would be great to get this question about how to reliably do general IO error handling settled.
The two possible ways I have the impression that there are now are
- By:
- Add a |treat-eof-as-error| port flag
- Add an optional third arg |first?| to |with-exception-catcher| and
-handler that makes the thunk be invoked first in case of exception. Internally there's two exception handler chains, the non-first that works just like the one today - an exception handler added makes it be invoked as first line in case of exception, and another chain that has priority over the non-first chain, that's invoked before it and where new handlers are added at the end and not at the beginning. (Perhaps internally they can be implemented as one chain only.)
- Make |with-exception-handler| exception handlers recursive (now they
make an infinite loop).
or
2): (Less general solution, so probably not desirable) By:
- Add a port-specific flag |io-error| to IO ports that's invoked in the
current place of both |raise| and eof.
In either of these two, the IO primitives need to be checked so that the IO error handling/|raise| calls are done in tail position / place that produces the primitive's return value anyhow.
Thanks and best regards, Mikael
2013/3/22 Mikael mikael.rcv@gmail.com
Dear Marc,
Spontaneously I think that the prospect of using with-exception-handler
as
you propose sounds better than adding custom error behavior code to the
IO,
as, the w.e.h. route would be more holistic in that it maintains the
error
handling mechanism in Gambit one in total in number; also,
It would work from a performance point of view as there is no overhead
per
IO primitive call that's successful, which accounts for almost all of
them.
The only potential issue with performance would be if the exception
handler
part would take a lot of time, though I guess it can be generalized that that is not an issue.
Then I guess the last point would be the design aspect that if somehow IO code would be run outside the current environment that the w.e.h. is installed in, the custom error behavior would disappear; that would
indeed
be a benefit with a port specific flag, that it's not subject to the same limitation. Though, from the practical use I see today, that more or less does not happen so it's fine.
I didn't think deeper about the possibility of w.e.h. before as I found myself without clarity on how the things I addressed in the previous
could be solved, as they need to be solved for it to be a practically viable solution.
Looking forward a lot to hear your take on those two-three things and hopefully get to a reliable io-error => #f soon =)
Thanks, Mikael
2013/3/20 Mikael
Hi Marc!
2013/3/18 Marc Feeley feeley@iro.umontreal.ca
The problem I see with the approach you propose (whether it uses a parameter or a port specific flag) is that the semantics of an
"io-error"
is vague. What is an IO error? The definition is important because exceptions that are IO errors are going to be processed using this new mechanism, and non-IO exceptions will use a different mechanism (normal exception handling).
The approach I propose does not have this problem because the
programmer
has complete control over the definition of an IO error. The exception object can be inspected to see if it qualifies as an IO error and an appropriate action can be taken. The definition of IO error can
depend on
the type of port, the type of primitive which caused the exception (read-u8, read-char, read), etc.
Marc
Aha. To really get this, there are two quite fundamental things about
the
applicability of the with-exception-handler possibility that I maybe
don't
get yet or at least would benefit of clarification, can we have a look
at
it?
Also last a question re semantics of io-error.
So, for the with-exception-handler mechanism to work out, it needs to go together with other use of exception handling use that's being done in
the
same scope.
In a setup where there's another exception handler *outside* the IO with-exception-handler, there would be no issue as the IO w.e.h. 's
handler
would be invoked first for any exception that occurs, and do its
matching
and handling.
In a setup where the other exception handler is made *inside* the IO w.e.h. though, any IO exception that arises within that exception
handler
will be picked up by it first, and for the IO w.e.h. thing to work out, that handler needs to be able to pass on the exception to the parent exception handler (which is the IO w.e.h.) completely in its original shape, in such a way that if the IO w.e.h. handler returns a value, that will be passed as return value to the original |raise| call.
An example of this would be a web-based PI calculator that uses
exception
handling locally in its PI calculate request thunk to pick up invalid
user
input.
So let's ask how this could be done.
Let's say below that we have a procedure (install-io-w.e.h. port thunk)
that
installs the IO w.e.h. that makes IO primitives return #f on exception,
so
that thunk is invoked with that w.e.h. installed.
Then, we have application logics (logics) that, aside from using IO, internally uses exception handling.
So a setup something like,
(define (logics) (with-exception-catcher (lambda (e) "Logics failed due to invalid user input!") (lambda () (pp (read-u8 broken-port)) (/ 0 0) ; This is to simulate an exception due to invalid user input. ))) (install-io-w.e.h. broken-port logics)
The desired behavior here is to print #f to the console and for logics to then return "Logics failed due to invalid user input!".
The issue now becomes, how would this local exception handler need to be implemented as for this to work out.
The local exception handler needs to be specific about what kind of
error
it looks for as to know which to handle locally and which to re-raise.
This
might be a complete PITA in some situations as you're looking for a catch-all behavior, as in the example above!
Perhaps the order of exception handlers could be tweaked somehow, so
that
the IO w.e.h. would get highest priority or something, though how could that be made as a 'clean' abstraction? I mean, who's in a place to
claim at
a general level that one exception is of higher prio than another? - different classes could be introduced, like, "user exceptions" and "io exceptions" or "system exception" (this would lead to an at least almost functional equivalent of the port specific flag solution, just with a
more
indirect code path!), or, the exception matching procedure could be exported to a separate mechanism, and the exception handler claiming the highest specificity in the matching would get to handle it e.g.
(with-exception-handler
exception-match exception-handler thunk) where exception-match takes an exception argument e and returns how well it matches the exception, i
duno
as a boolean or 0-10 or a symbol.
Or, a global parameter object |is-nonlocal-exception?| could be introduced that any exception handler is free to invoke as to check if
it
should re-raise the exception, and to overlap.. hmm, a more general solution would be better.
Do you see any general solution to this specificity problem?
Now to get to the next thing, let's just presume there's a solution to this and we represent it in this example as a (if (is-nonlocal-exception? e) (raise e) condition in the local exception handler, again not because this would necessarily represent a general solution but just to get on to the next thing in the reasoning; so now
we
have
(define (logics) (with-exception-catcher (lambda (e) (if (is-nonlocal-exception? e) (raise e) "Logics failed due to invalid user input!")) (lambda () (pp (read-u8 broken-port)) (/ 0 0) ; This is to simulate an exception due to invalid user input. ))) (install-io-w.e.h. broken-port logics)
Now, how do you make this *parent* exception handler (the IO w.e.h.)
that
got the exception passed to it, able to pass a return value to the
original
|raise| call?
This is required for the exception handling-based IO error handling behavior we're looking for to work.
The problem reduces to
(define (logics) (raise "Please return 'properly-handled!"))
(define (proxy-exception-handler/catcher2 thunk) (lambda () (with-exception-catcher (lambda (e) (raise e)) thunk)))
(define (proxy-exception-handler/catcher1 thunk) (lambda () (with-exception-handler (lambda (e) (raise e)) thunk)))
(define (parent-exception-handler thunk) (continuation-capture (lambda (cont) (with-exception-handler (lambda (e) 'properly-handled!) thunk))))
where proxy-exception-handler/catcher 1 & 2 are to represent an
arbitrary
chain of exception handlers that logics code may come up with. The
intended
behavior is
(parent-exception-handler (proxy-exception-handler/catcher1
(proxy-exception-handler/catcher2
logics))) => 'properly-handled!
(parent-exception-handler (proxy-exception-handler/catcher1 logics)) => 'properly-handled!
(parent-exception-handler (proxy-exception-handler/catcher2 logics)) => 'properly-handled!
Actually evaluating these three tests showed:
(parent-exception-handler (proxy-exception-handler/catcher1
(proxy-exception-handler/catcher2
logics))) => infinite loop (!)
(parent-exception-handler (proxy-exception-handler/catcher1 logics)) =>
infinite
loop (!)
(parent-exception-handler (proxy-exception-handler/catcher2 logics)) => 'properly-handled!
To start with, great that we see that with-exception-catcher delivers
out
of the box for this usecase!
Thus we have with-exception-handler left. I guess the best way would be if with-exception-handler inherently somehow would deliver for this, so that support for this kind of use would be transparent and not require possible updates of user code (e.g. any typical user code such as a PI calculator etc. could without needing code review just be run within a
web
server that uses this special IO error handling).
Is there any way to make with-exception-handler deliver for this
usecase?
Last, what about that for introducing a port specific flag there would
be
the issue that the semantics of an IO error is vague -
Maybe you see something here I didn't get. As IO error for a port would count any error reported from the OS about the port, as well as timeouts within Gambit's IO system.
So this would correspond to any OS IO primitive invocation that gives an error return value (other than one that asks for a reiteration of the procedure, which some of them come with).
Another way to relate to it would be that such a port specific flag
would
serve to protect from requirement of programmer or admin intervention
for
any IO error that could possibly come up regarding the addressed ports.
What do you see here?
Best regards, Mikael
Afficher les réponses par date