[racket] hack: implicit function arguments

From: Jon Rafkind (rafkind at cs.utah.edu)
Date: Sat Aug 14 01:01:41 EDT 2010

  I came up with this little hack that lets you avoid giving an explicit 
argument list to functions. Arguments are discovered by usages of 
underscores followed by a number, like _1 and _2. Partly inspired by 
scala; sure to make your blood boil if you love hygiene.

;;; usage
(define/implicit foo1 (printf "~a ~a ~a\n" _8 _9 _8))
(foo1 5 12)

;;; code
#lang racket/base

(require (for-syntax racket/base
                      racket/list
                      syntax/parse
                      )
          racket/stxparam)

(define-syntax-rule (implicits all thing ...)
   (begin
     (define-syntax-parameter thing (lambda (stx)
                                   (raise-syntax-error #f (format "~a 
can only be used in a
  define/implicit function" 'thing))))
     ...
     (provide thing ...)
     (define-for-syntax all (list #'thing ...))))

(implicits all-implicits _1 _2 _3 _4 _5 _6 _7 _8 _9 _10)

(provide define/implicit lambda/implicit)
(define-syntax (lambda/implicit stx)
   (define (find-implicits stx)
     (define-syntax-class implicit
                          [pattern x:identifier
                                   #:when (ormap (lambda (y)
                                                   (free-identifier=? y 
#'x))
                                                 all-implicits)])
     (remove-duplicates
       (filter values
               (syntax-parse stx
                 [x:implicit (list #'x)]
                 [(x ...) (apply append (map find-implicits 
(syntax->list #'(x ...))))]
                 [else (list #f)]))
       free-identifier=?))
   (syntax-parse stx
     [(_ body ...)
      (define implicit-arguments (find-implicits stx))
      (with-syntax ([(new-arg ...) (generate-temporaries 
implicit-arguments)]
                    [(implicit ...) implicit-arguments])
        #'(lambda (new-arg ...)
            (syntax-parameterize ([implicit (make-rename-transformer 
#'new-arg)] ...)
                                 body ...)))]))

(define-syntax-rule (define/implicit name body ...)
                     (define name (lambda/implicit body ...)))



Posted on the users mailing list.