Skip to content

Instantly share code, notes, and snippets.

@takikawa
Forked from greghendershott/gist:4122971
Created November 21, 2012 05:20
Show Gist options
  • Save takikawa/4123230 to your computer and use it in GitHub Desktop.
Save takikawa/4123230 to your computer and use it in GitHub Desktop.
#lang racket
(require (for-syntax syntax/parse
syntax/parse/experimental/template
racket/syntax
racket/list))
;; A syntax class to recognize function arguments:
(begin-for-syntax
(define-splicing-syntax-class argspec
#:description "argument"
#:attributes (id def kw)
(pattern id:id #:with kw #f #:with def #f)
(pattern [id:id def:expr] #:with kw #f)
(pattern (~seq kw:keyword id:id) #:with def #f)
(pattern (~seq kw:keyword [id:id def:expr]))))
(define-syntax (lam stx)
;; Parse into argspecs (e.g. "#:kw [n 0]" is one thing)
(syntax-parse stx
[(_ (arg:argspec ...) body ...+)
;; append* them down to decl format (e.g. #:kw [n 0] is again
;; multiple things), which we need for the lambda declaration.
(template
(lambda ((?@ . arg) ...)
body ...))]))
;; Use `lam'
(define f1
(lam (x y)
(list x y)))
(f1 1 0)
;; => '(1 0)
;; Good.
;; Now a `define' variation:
(define-syntax (define-lam stx)
(syntax-parse stx
[(_ (name:id arg:expr ...) body ...+)
#'(define name (lam (arg ...) body ...))]))
;; Use `define-lam'
(define-lam (f2 x y)
(list x y))
;; => x: unbound identifier in module
;; in: x
;; Huh?
(f2 1 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment