Skip to content

Instantly share code, notes, and snippets.

@gwatt
Last active February 14, 2017 00:56
Show Gist options
  • Save gwatt/42a5cde08adcfc351e1dad545738a5f6 to your computer and use it in GitHub Desktop.
Save gwatt/42a5cde08adcfc351e1dad545738a5f6 to your computer and use it in GitHub Desktop.
define-curried/lambda-curried for r6rs scheme
(library (curry)
(export define-curried lambda-curried)
(import (rnrs))
(define-syntax lambda-curried
(lambda (x)
(syntax-case x ()
[(_ () b b* ...) #'(lambda () b b* ...)]
[(_ arg* b b* ...) (identifier? #'arg*) #'(lambda arg* b b* ...)]
[(_ (arg* ...) b b* ...)
#'(letrec
([func (lambda (arg* ...) b b* ...)]
[arg-count (length '(arg* ...))]
[partial-apply
(lambda (incoming current count)
(let ([new-count (+ count (length incoming))])
(cond
[(= arg-count new-count)
(apply func (append current incoming))]
[(> arg-count new-count)
(lambda args (partial-apply args (append current incoming) new-count))]
[else (error 'lambda-curried "Too many arguments")])))])
(lambda args (partial-apply args '() 0)))]
[(_ (arg* ... . rest) b b* ...)
#'(letrec
([func (lambda (arg* ... . rest) b b* ...)]
[arg-count (length '(arg* ...))]
[partial-apply
(lambda (incoming current count)
(let ([new-count (+ count (length incoming))])
(if (> arg-count new-count)
(lambda args (partial-apply args (append current incoming) new-count))
(apply func (append current incoming)))))])
(lambda args (partial-apply args '() 0)))])))
(define-syntax define-curried
(syntax-rules ()
[(_ (func arg* ...) b b* ...)
(define func
(lambda-curried (arg* ...)
b b* ...))]
[(_ (func arg* ... . rest) b b* ...)
(define func
(lambda-curried (arg* ... . rest)
b b* ...))]))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment