Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== Outdated egg! This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for [[/eggref/5/simple-exceptions|the CHICKEN 5 version of this egg]], if it exists. If it does not exist, there may be equivalent functionality provided by another egg; have a look at the [[https://wiki.call-cc.org/chicken-projects/egg-index-5.html|egg index]]. Otherwise, please consider porting this egg to the current version of CHICKEN. [[tags: egg]] [[toc:]] == Exceptions made easy Chicken's condition system is versatile and flexible, but apart from the two high level exception handlers, handle-exceptions and condition-case, not very user friendly. In particular the low-level exception handler, with-exception-handler, must be used with extreme care to avoid non-terminating loops. Moreover creating and inspecting condition-objects is cumbersome. So this library introduces some procedures and macros to facilitate matters. Exceptions are introduced as special conditions, to be more precise, [composite] conditions of kind exn, which all have properties message, location and arguments, which can easyly be accessed by procedures of that very name. They are constructed by separating the general property, message, and the general kinds, from the special properties, location and arguments, the latter being considered as parameters of an exception. In other words, one can define a global exception-variable of a special kind, e.g. <enscript highlight=scheme> (define assert-exn (make-exception "assertion violated" 'assert)) </enscript> which can then be used within the definition of a procedure, foo say, as follows <enscript highlight=scheme> (raise (assert-exn 'foo 'xpr)) </enscript> Here, raise is a version of abort with improved error messages. The exception raised can now be handled in the usual way, preferably <enscript highlight=scheme> (condition-case (foo arg) ((exn assert) ...)) </enscript> or <enscript highlight=scheme> (handle-exceptions exn (if ((exception-of? 'assert) exn) ...) (foo arg)) </enscript> but other handlers are provided as well, in particular, guard of R6RS and R7RS, and with-exn-handler, which has the same syntax as Chicken's with-exception-handler, but avoids its subtleties. For example, the follwing code does what you expect, it returns 0. <enscript highlight=scheme> (with-exn-handler (lambda (exn) 0) (lambda () (car '()))) </enscript> without looping forewer, what with-exception-handler would have done. Another useful macro is assert* which -- contrary to assert -- allows many expressions to be tested and demands a location argument, which is used to produce a meaningful error-message. === The interface ==== current-exception-handler <parameter>(current-exception-handler [new-handler])</parameter> chicken's handler parameter reexported. ==== exceptions <procedure>(exceptions [sym])</procedure> documentation procedure. ==== exception? <procedure>(exception? xpr)</procedure> type predicate. Note, that each exception is a condition of kind exn. ==== exn? <procedure>(exn? xpr)</procedure> alias to exception? ==== exception-of? <procedure>(exception-of? kind-key)</procedure> returns a unary predicate, which checks, if its argument expression is an exception of kind kind-key, a symbol. ==== exn-of? <procedure>(exn-of? kind-key)</procedure> alias to exception-of? ==== make-exception <procedure>(make-exception msg . kind-keys)</procedure> Returns a procedure of at least one argument, a symbol describing the location of its call, and an optional other argument, a list of arguments, which creates an exception of kinds kind-keys, message msg, as well as the given location and arguments. ==== make-exn <procedure>(make-exn msg . kind-keys)</procedure> alias to make-exception ==== location <procedure>(location exn)</procedure> returns the location property of its exception argument. ==== message <procedure>(message exn)</procedure> returns the message property of its exception argument. ==== arguments <procedure>(arguments exn)</procedure> returns the arguments property of its exception argument. ==== raise <procedure>(raise exn)</procedure> raises its argument, i.e. calls (current-exception-handler) with exn. In essence chicken's abort. ==== with-exn-handler <procedure>(with-exn-handler handler thunk)</procedure> A save version of chicken's low-level with-exception-handler. Sets the current-exception-handler to handler for the dynamic extent of its call and executes thunk in this context. ==== condition-case <macro>(condition-case xpr ([var] (kind ...) body) . other-clauses)))</macro> Chicken's highest level exception-handler reexported. ==== handle-exceptions <macro>(handle-exceptions exn handle-xpr xpr . xprs)</macro> Chicken's high level exception handler reexported. ==== guard <macro>(guard (exn cond-clause . cond-clauses) xpr . xprs)</macro> The high level exception handler of R6RS and R7RS. Sets the current-exception-handler to an exception-handler created from exn und the supplied cond-clauses for the dynamic extent of its call and executes the body xpr . xprs in this context. ==== assert* <macro>(assert* loc xpr . xprs)</macro> checks the expressions xpr . xprs in sequence and raises an exception for the first failing expression with location property loc and arguments property the failing expression quoted. ==== argument-exception <procedure>(argument-exception loc arg ...)</procedure> raised when a precondition is violated. Can be catched with (exn argument) ==== argument-exn <procedure>(argument-exn loc arg ...)</procedure> alias to argument-exception ==== result-exception <procedure>(result-exception loc arg ...)</procedure> raised when a postcondition is violated. Can be catched with (exn result) ==== result-exn <procedure>(result-exn loc arg ...)</procedure> alias to result-exception ==== named-lambda <macro>(named-lambda name args xpr . xprs)</macro> can replace anonymous procedures and can be used recursively. ==== << <procedure>(<< x loc .. x? ...)</procedure> precondition test: passes x unchanged only if all predicates x? return #t on it, raises an argument-exception at location loc, if given, or '<< otherwise ==== >> <procedure>(>> x loc .. x? ...)</procedure> postcondition test: passes x unchanged only if all predicates x? return #t on it raises a result-exception at location loc, if given, or '>> otherwise ==== true? <procedure>(true? xpr)</procedure> returns always #t ==== false? <procedure>(false? xpr)</procedure> returns always #f === Examples <enscript highlight=scheme> (use simple-exceptions) ((named-lambda ! (n) (if (zero? n) 1 (* n (! (- n 1))))) 5) ; -> 120 (<< 5 integer? odd? (named-lambda 5<= (x) (<= 5 x))) ; -> 5 (condition-case (>> 5 integer? even?) ((exn results) #f)) ; -> #f (<< ((lambda () #f)) boolean?) ; -> #f (define foo-exn (make-exception "foo-msg")) (define bar-exn (make-exception "bar-msg" 'bar)) (exception? (foo-exn 'nowhere)) (bar-exn 'nowhere) (exception? (bar-exn 'nowhere)) ; -> #t ((exception-of? 'bar) (bar-exn 'nowhere)) ; -> #t ((exception-of? 'bar) (foo-exn 'nowhere)) ; -> #f (arguments ((make-exception "msg" 'baz) 'nowhere "bar")) ; ,> (list "bar") ((exception-of? 'key) ((make-exception "msg" 'key) 'nowhere)) ; -> #t (define list-empty-exn (make-exception "argument list empty" 'list-empty)) (define (try-car lst) (if (null? lst) (raise (list-empty-exn 'try-car lst)) (car lst))) ;; exception handler procedure (with-exn-handler (lambda (exn) (if ((exception-of? 'list-empty) exn) #f #t)) (lambda () (try-car '()))) ; -> #f (with-exn-handler (lambda (e) 0) (lambda () (/ 5 0))) ; -> 0 (guard (exn (((exception-of? 'foo) exn) (location exn)) ((exception? exn) (message exn)) (else (arguments exn))) (raise ((make-exception "msg" 'foo) 'location-unknown))) ; -> 'location-unknown) </enscript> == Last update Feb 17, 2017 == Author [[/users/juergen-lorenz|Juergen Lorenz]] == License Copyright (c) 2014-2017, Juergen Lorenz All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. == Version History ; 0.6 : bug in <<< and >>> fixed ; 0.5 : <<< and >>> added, pre- and post-exceptions renamed argument- and result-exn, some aliases added ; 0.4 : named-lambda added ; 0.3.1 : << and >> now procedures ; 0.3 : <<, >>, pre-exception and post-exception from bindings ; 0.2 : with-handler renamed with-exn-handler ; 0.1 : initial import
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you add 0 to 15?