Skip to content

Instantly share code, notes, and snippets.

@samdphillips
Created February 24, 2022 15:43
Show Gist options
  • Select an option

  • Save samdphillips/2373d19f917e3553388defc2731c3d10 to your computer and use it in GitHub Desktop.

Select an option

Save samdphillips/2373d19f917e3553388defc2731c3d10 to your computer and use it in GitHub Desktop.
Go style defer in Racket
#lang racket/base
(require "defer.rkt")
(define (x)
(define f (open-input-file "/dev/random"))
(defer (begin (println "closing f") (close-input-port f)))
(displayln (bytes->list (read-bytes 32 f))))
#lang racket/base
(require (for-syntax racket/base
syntax/parse/lib/function-header)
racket/stxparam
syntax/parse/define)
(define-syntax-parameter defer
(lambda (stx)
(raise-syntax-error
#f "use of defer not in a with-defer block" stx)))
(define-syntax-parse-rule (with-defer e ...+)
(let ([current-defers null])
(syntax-parameterize ([defer
(syntax-rules ()
[(_ de) (set! current-defers
(cons (lambda () de)
current-defers))])])
(dynamic-wind
void
(lambda () e ...)
(lambda ()
(for-each (lambda (c) (c)) current-defers))))))
(define-syntax-parse-rule (defer-lambda args:formals body ...+)
(lambda args (with-defer body ...)))
(define-syntax-parser defer-define
[(_ v:id e) #'(define v e)]
[(_ h:function-header body ...+)
#'(define h.name (defer-lambda h.params body ...))])
(provide with-defer
defer
(rename-out [defer-lambda lambda]
[defer-define define]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment