Update: Now part of brev-separate.
A friend suggested a define-curry
macro and to me what immediately
came to mind was something like this:
(define-curry (foo bar baz bax)
(print baz)
(+ bar baz bax))
(=
(foo 100 20 3)
((foo 100) 20 3)
((foo 100 20) 3)
((foo) 100 20 3)
(((foo) 100) 20 3)
(((foo 100) 20) 3)
((((foo) 100) 20) 3))
Prints seven 20 and evals #t
.
Here is the implementation:
(import miscmacros)
(define-syntax-rule
(define-curry (name . args) . body)
(define (name . friends)
(if (= (length friends) (length 'args))
(apply (lambda args . body) friends)
(lambda stragglers
(apply name (append friends stragglers))))))
Here is a partial application functional combinator that’s arbitrary
arity but not recursive. It’s a replacement for cut
when every slot
is at the end of the arg list.
(define (🍛 name . args)
(lambda stragglers
(apply name (append args stragglers))))
(= 54321
((🍛 + 1 20 300) 4000 50000)
((🍛 (🍛 + 1 20 300) 4000) 50000))
⇒ #t
I’ve seen people asking “why use the macro when you have this partial applicator”?
The advantages of this applicator is that you get arbitrary arity and that you can use it on existing procedures. Pretty great and I use it a lot.
The advantage of the macro, for fixed arity functions, is that it lets you repeatedly curry it. You can add as many or as few argument as you want and until you’ve jammed all the args in there, it’s still a proc. Only as you put those last args in place is when that procedure’s called for the value. I don’t use that as much because it’s for situations when
In other words, pretty niche. I just think it’s neat.
For example:
(map (foo 12 45) '(20 30 40))
or
(map (foo 12) '(12 16) '(80 1000))
The example I used earlier:
((🍛 (🍛 + 1 20 300) 4000) 50000)
If that had been a function made with define-curry
instead, say it was called jank
, we could’ve:
(((jank 1 20 300) 4000) 50000)
The recursive partial application is built in.