Problem 5: K-Curry (100 pts)

Write the macro k-curry, which takes in a function fn, a list of the function's arguments args, a list of k values to substitute in for these arguments, and a sorted list of k non-negative indices specifying which arguments to pass values from vals into.

k-curry will return a new function which takes in whatever arguments remained from fn's list of arguments, with the arguments picked out by indices automatically filled in with the values from vals.

Hint: Write helper functions outside the macro, and use them inside the macro.

(define-macro (k-curry fn args vals indices)
  ''YOUR-CODE-HERE
)

;;; Tests
; scm> (define (f a b c d) (- (+ a c) (+ b d)))
; f
; scm> (define minus-six (k-curry f (a b c d) (2 4) (1 3)))
; minus-six
; scm> (minus-six 8 10) ; (- (+ 8 10) (+ 2 4))
; 12

In the example above, we first defined a function f with four arguments, a, b, c, and d.

We next use k-curry to define another function minus-six. The expression (k-curry f (a b c d) (2 4) (1 3)) should be interpreted as follows:

  1. For the given function f whose parameters are named a, b, c, and d,
  2. we will substitute the provided vals values 2 and 4
  3. for the 1st parameter of f (i.e., b) and the 3rd parameter of f (i.e., d), according to indices
  4. and return the partially applied function.

By substituting 2 and 4 for b and d, respectively, the function f will be equivalent to (lambda (a c) (- (+ a c) (+ 2 4)), denoted by its name minus-six.