On Scheme

Thoughts on Scheme and teaching Scheme

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 (
               (caddadr
                (lambda (x)
                  (car (cdr (cdr (car (cdr x)))))))
               (cadadr
                (lambda (x)
                  (car (cdr (car (cdr x))))))
               (caadr
                (lambda (x)
                  (car (car (cdr x)))))
               (gen-let-and-lambda
                (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))))))))
                        )))
               (p-c-transformer
                (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)))))))
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: