Skip to content

Instantly share code, notes, and snippets.

@AlexKnauth AlexKnauth/.gitignore
Last active Feb 8, 2016

Embed
What would you like to do?
Allowing multiple return values to include keywords in racket
compiled/
doc/
*~
#lang racket/base
(provide call-with-current-continuation
let/cc
values
call-with-values
)
(require syntax/parse/define
(only-in racket/base [values rkt:values] [let/cc rkt:let/cc]))
(module+ test
(require rackunit))
;; The continuation-mark-key for storing continuations that accept
;; keyword arguments.
(define kw-continuation-key
(make-continuation-mark-key 'keyword-continuation))
;; A version of call-with-current-continuation that finds a
;; continuation that accepts keyword arguments, if it exists.
(define (call-with-current-continuation proc)
(rkt:let/cc k
(call-with-immediate-continuation-mark
kw-continuation-key
proc
k)))
(define-simple-macro (let/cc k:id body:expr ...+)
(call-with-current-continuation (λ (k) body ...)))
;; A version of values that accepts keywords and applies those
;; keywords to the current kw-continuation.
(define values
(make-keyword-procedure
(lambda (kws kw-args . args)
(let/cc k
(keyword-apply k kws kw-args args)))
rkt:values))
;; Is this the right implementation?
(define (call-with-values generator receiver)
(let/cc k
(with-continuation-mark kw-continuation-key (compose k receiver)
(generator))))
(module+ test
;; test call-with-values and values
(check-equal? (call-with-values
(λ () (values #:a 3))
(λ (#:a a) a))
3)
;; test let/cc
(check-equal? (+ 1 (let/cc k (+ 1000 (k (+ 5 5)))))
11)
;; test let/cc within call-with-values
(check-equal? (+ 1 (call-with-values
(λ () (let/cc k (+ 1000 (k #:a (+ 5 5)))))
(λ (#:a a) (* 4 a))))
41)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.