Search code examples
reflectionlispschememetaprogramminghomoiconicity

Traversing Scheme function as a list


Isn't it possible to treat functions in Scheme as any other list?

Basically, what I want do to is something like this:

(define (foo) "hello")

(cdr foo)  ; or similar, should return the list ((foo) "hello")

I've found a similar discussion about this, and I feel a bit disappointed if this is not possible with Scheme. If so, why is this impossible? Is it possible in other lisps?

EDIT: Changed (cdr 'foo) to (cdr foo) -- it was misleading. I'm asking, why can't I access a function as a list?


Solution

  • I have often wanted to be able to do the same thing csl. Below is a quick example of how you could go about doing this in mzscheme.

    DrScheme 4.2

    (module qdefine mzscheme
      (provide ;(all-from-except mzscheme let)
       (rename define olddefine)
       (rename quote-define define)
       (rename quote-cdr cdr)
       (rename quote-car car))
    
      (define define-list '())
      (define define-list-add 
        (lambda (key value)
          (set! define-list (cons `(,key ,value) define-list))))
    
      (define-syntax quote-define
        (syntax-rules ()
          ((_ (pro-name args ...) body ...) 
           (begin
             (define (pro-name args ...) body ...)
             (define-list-add pro-name  '((pro-name args ...) body ...))))
          ((_ pro-name pro) (begin
                              (define pro-name pro)
                              (define-list-add pro-name 'pro)))
    
          ))
    
      (define quote-cdr (lambda (lst)
                          (if (procedure? lst)
                              (cdr (cadr (assoc lst define-list)))
                              (cdr lst))))
    
      (define quote-car (lambda (lst)
                          (if (procedure? lst)
                              (car (cadr (assoc lst define-list)))
                              (car lst))))
      )
    (require 'qdefine)
    
    (define testfunc (lambda (args) args))
    (cdr testfunc)
    (car testfunc)
    
    (define (testfunc2 test) 'blah)
    (cdr testfunc2)
    (car testfunc2)
    
    (define testlist '(1 2 3 4 5 6 'a))
    (cdr testlist)
    (car testlist)
    

    Outputs:

    ((args) args)
    lambda
    ('blah)
    (testfunc2 test)
    (2 3 4 5 6 'a)
    1
    >