-
-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
try
- another try/catch/finally inspired by Gerbil Scheme
#10
Comments
Thank you for your contribution! If you haven’t already please take the time to fill in the form https://forms.gle/Z5CN2xzK13dfkBnF7 Bw |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Macro
A
try
/catch
/finally
macro inspired by Gerbil Scheme'stry
macro in:std/sugar
.Source code: https://github.com/AlexKnauth/try-catch-finally/blob/main/try-catch-finally-lib/main.rkt
Documentation: https://docs.racket-lang.org/try-catch-finally/index.html
Example
An example with
try
/catch
:This runs a computation that raises a syntax exception, and catches that with a handler written after the main body, rather than written before as in
with-handlers
.An example with
try
/finally
:This runs a computation that exits due to a continuation jump, and still runs the "post-body" set up in the
finally
.Before and After
Similarly to #9 and #12, this also can replace uses of
with-handlers
withtry
/catch
, and replace many uses ofdynamic-wind
withtry
/finally
.However, part of the reason I wanted to provide the same functionality as Gerbil Scheme was to compare my
syntax-parse
implementation to their procedural /syntax-case
implementation, and therefore:Gerbil Scheme's
try
implementation is here:https://github.com/vyzo/gerbil/blob/fa9537be0848e54d2c68165503b9cc48babb9334/src/std/sugar.ss#L32-L97
With supporting function definitions here:
https://github.com/vyzo/gerbil/blob/17fbcb95a8302c0de3f88380be1a3eb6fe891b95/src/gerbil/runtime/gx-gambc0.scm#L1625-L1636
a. My
try
macro doesn't need a supportingwith-catch
function because it can use a combination of thesyntax/parse
technique Variants with Uniform Meanings and the existing Racketwith-handlers
form.b. Gerbil's supporting function
with-unwind-protect
uses mutable state to make a "one use" closure dynamically check that it's only called once. While my version,call-with-try-finally
, uses a continuation-barrier as suggested by SamPh on Discord, to accomplish the same without mutable state.Their supporting runtime functions take 11 sloc while mine take only 3 sloc, mostly due to Racket features such as
with-handlers
and continuation-barriers that Gerbil's version doesn't have.a. My
catch
andfinally
literals use a compile-time helper functionnot-allowed-as-an-expression
to get a better error message, while Gerbil's version uses a simple emptydefrules
to get a genericBad syntax
error message.b. My
try
macro uses syntax-parse's...+
to express one-or-more repetition, while Gerbil's version uses manualnull?
checks andstx-null?
checks, seen in theirgenerate-thunk
helper function and theirfinally
case.c. My
try
macro uses a syntax-parsesyntax-class
for recognizingbody
expressions that aren'tcatch
orfinally
clauses, using the~not
pattern to exclude them. While Gerbil's version uses a namedlet
loop with 2 extra nestedsyntax-case
expressions (beyond the normalsyntax-case
at the top) to separate body expressions fromcatch
andfinally
clauses.d. My
try
macro uses a syntax-parsesyntax-class
for handlingcatch
clauses as Variants with Uniform Meanings allowing repetition with ellipses, while Gerbil's version uses the helper functiongenerate-catch
, with its ownwith-syntax
, namedlet
loop,match
, andsyntax-case
expressions, in combination with yet another namedlet
loop and another nestedsyntax-case
expression (beyond the ones mentioned above) in the main body of the macro to separate thecatch
clauses from thefinally
clause.e. My
try
macro uses a syntax-parsesyntax-class
for handling thefinally
clause, while Gerbil's version uses a helper functiongenerate-fini
and 2 differentfinally
cases in differentsyntax-case
expressions in the main body of the macro. One of these is to separatebody
expressions fromfinally
in the case when there are nocatch
es in between, and the other is to separatecatch
clauses fromfinally
. Their firstfinally
case requires a manualstx-null?
check to make sure nothing comes afterfinally
, while their secondfinally
case encodes that into asyntax-case
pattern for a 1-element list. Syntax-classes allow mytry
macro to express this simply by putting thefinally-clause
pattern at the end of the main syntax-pattern, after the previous patterns and their ellipses.Their syntax definitions take 62 sloc while mine take 28 sloc, with
syntax/parse
features such as syntax-classes and better ellipsis support making it much shorter, as well aswith-handlers
allowing the output to be simpler and allowing the ellipsis repetitions of syntax-classes to do more of the work. I also subjectively find mine easier to read, though I am biased on that of course.Licence
I confirm that I am submitting this code under the same MIT License that the Racket language uses. https://github.com/AlexKnauth/try-catch-finally/blob/main/LICENSE.txt
and that the associated text is licensed under the Creative Commons Attribution 4.0 International License
http://creativecommons.org/licenses/by/4.0/
The text was updated successfully, but these errors were encountered: