On Scheme

Thoughts on Scheme and teaching Scheme

Archive for March 8th, 2006

Incomplete Function Calls

Posted by Peter on March 8, 2006

Today I am have been exploring the idea of incomplete function calls, which I think I first heard of through some other language. The idea is that you can call a function with a partial parameter list, and instead of creating an error the function returns a new function instead. So if x = f(1, 2) and f takes three parameters then x(y) = f(1, 2, y). Because I don’t know how to auto-detect when a function is missing parameters my syntax won’t look quite like this. Also I will have the caller supply X wherever there is a missing parameter (so long as you don’t want to pass the variable X, all will be fine). Thus my scheme version is (define x (ic-call f 1 2 X)). Note that I use let binding to ensure that the parameters to ic-call are evaluated only once, multiple calls to the function created will not re-evaluate the parameters. I also use gensyms to rule out variable capture. I will explain my macro tomorrow, however I know it is long and ugly, not to mention uncommented. This is partly due to the complication of using gensyms. If anyone wants to give me some pointers as how to clean it up they would be appreciated.
Example of use: ((ic-call (lambda (x y z) (* x (+ y z))) X 2 X) 2 3)
Result: 10

(define-syntax ic-call
    (lambda (x)
      (letrec (
                (lambda (x)
                  (car (cdr (cdr (car (cdr x)))))))
                (lambda (x)
                  (car (cdr (car (cdr x))))))
                (lambda (x)
                  (car (car (cdr x)))))
                (lambda (params existing)
                  (cond ((null? params) existing)
                        ((eq? (car params) 'X)
                           (let ((t-sym (gensym)))
                             (gen-let-and-lambda (cdr params)
                                                 (cons (car existing)
                                                       (list (list (caadr existing)
                                                                   (append (cadadr existing) (list t-sym))
                                                                   (append (caddadr existing) (list t-sym))))))))
                        (else (let ((t-sym (gensym)))
                                (gen-let-and-lambda (cdr params)
                                                    (cons (append (car existing) (list (list t-sym (car params))))
                                                          (list (list (caadr existing)
                                                                      (cadadr existing)
                                                                      (append (caddadr existing) (list t-sym))))))))
                (lambda (statement)
                  (cons 'let
                        (gen-let-and-lambda (cdr statement) `(() (lambda () (,(car statement))))))))
       (datum->syntax-object (syntax k) (p-c-transformer (cdr (syntax-object->datum x)))))))

Posted in Exploring Scheme | Leave a Comment »