Reflection 作为列表的遍历方案函数

Reflection 作为列表的遍历方案函数,reflection,lisp,scheme,metaprogramming,homoiconicity,Reflection,Lisp,Scheme,Metaprogramming,Homoiconicity,难道不能将Scheme中的函数视为任何其他列表吗 基本上,我想做的是这样的: (define (foo) "hello") (cdr foo) ; or similar, should return the list ((foo) "hello") 我发现了这一点,如果这个计划不可能实现,我感到有点失望。如果是这样,为什么这是不可能的?在其他Lisp中可能吗 编辑:将(cdr'foo)更改为(cdr-foo)--这有误导性。我在问,为什么我不能以列表的形式访问函数 'foo计算为符号,您不

难道不能将Scheme中的函数视为任何其他列表吗

基本上,我想做的是这样的:

(define (foo) "hello")

(cdr foo)  ; or similar, should return the list ((foo) "hello")
我发现了这一点,如果这个计划不可能实现,我感到有点失望。如果是这样,为什么这是不可能的?在其他Lisp中可能吗


编辑:将(cdr'foo)更改为(cdr-foo)--这有误导性。我在问,为什么我不能以列表的形式访问函数

'foo计算为符号,您不能获取符号的CDR


您可能想做的是(cdrfoo),但这不起作用。FOO的值是一个过程,而不是一个列表。

您可以使用
pp
pretty print
以列表的形式访问函数。也就是说,您可能还需要在调试模式下运行代码。然而,这非常依赖于实现。我知道它可以在Gambit-C中工作。

您的
定义
表单不是一个函数,而是一个函数定义。事实上,它是

(define foo
  (lambda ()
    "hello"))
Lambda
可以被认为是“编译器调用”。在本例中,它生成一个返回该字符串的函数<代码>定义然后将此函数绑定到符号
'foo

将此与

(define foo "hello")
它仅将字符串绑定到符号
'foo
(cdr foo)
会返回什么

现在,可以想象,在将函数绑定到符号时,某些方案实现实际上保存了
lambda
表单,或者可以选择保存该表单。您必须检查文档,但这意味着的纯解释肯定会对性能产生影响

但是,如果您成功地获得了这个,它将返回
lambda
表单,而不是
define
表单。

(define(foo)…
生成一个编译对象,它是一个值-一个过程。
不能对其进行迭代,因为它不是s表达式

像其他人建议的那样,您应该查看您的编程环境,并查看

MIT Scheme有能力完成这类任务。(如果你真的愿意,请对此进行评论,我会给你代码。我必须找到一些未记录的函数来实现它。)

但是,它不在Scheme语言定义中,因此实现不必允许它。原因是为了使函数更快,一个好的方案实现将修改函数。这意味着既要用不同的语言(机器代码或相当低级的语言)重写它们,又要去掉不需要的任何位—例如,
+
函数通常必须检查其参数是否为数字,如果是,则检查哪种数字,但如果您的函数是调用
+
的循环,您可以在开始时只检查一次,从而使功能更快

当然,即使有了所有这些东西,你仍然可以不费吹灰之力地保存列表。但是,如果您试图修改列表,它将如何工作


(同样,你可以让它工作。这对实现者来说只是更多的工作,而且由于它通常不在程序中使用,大多数人可能只是不想麻烦。)

我经常希望能够做同样的事情csl。 下面是一个如何在mzscheme中执行此操作的快速示例

方案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)
产出:

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

guile>(定义(foo-bar)'baz)
guile>(程序源foo)
(lambda(bar)(引用baz))
guile>(cdr(过程源foo))
((酒吧)(引用baz))
诡计>


是 啊我在问为什么我不能cdr一个过程。因为这个过程不是一个列表。您只能使用cdr列表。这个过程可能是一堆机器指令。这不是一个令人满意的答案——列表也可以这样说,因为您不知道列表在内存中是如何表示的。@csl:CDR是为conses和list定义的。没别的了。所以CDR适用于列表。因为过程不是列表,所以它不会工作。过程是另一回事。当然,我很乐意得到代码。也许把它发到网上(gist/pastebin)?对不起,我以为我有它,但我只是看了看,找不到它。我基本上是通过下载麻省理工学院的scheme源代码,找到它们是如何表示解释过程的,并使用了该文件中的一些函数,这些函数碰巧在REPL上可用,尽管它们可能不应该是。非常好的解释!难道不可能创建我自己的define表单来编译代码(通过eval)并保留源代码吗?这会很有帮助。有人知道如何在其他方案实现中做到这一点吗?根据实现的不同,我认为您可以使用defmacro或syntactic闭包来做类似的事情。我想要(define blah(lambda…)(define blah(lambda(…)new code(blah…))的宏等价物,但我还没有找到一个方案实现,可以直接实现这一点。我还发现了一些有趣的注意事项: