【发布时间】:2017-06-03 11:55:12
【问题描述】:
我遇到了一些异国情调。我需要比较函数,而是通过它们的“起源”而不是“实例”。这就是我的真正意思:
(define-values (a b c d) (values #f #f #f #f))
(define (f x)
(let ([g (λ (y) (printf "Please tell ~a this is ~a\n" x y))]
[h (curry printf "Don't tell ~a this is ~a\n" x)])
(if a
(set! b g)
(set! a g))
(if c
(set! d h)
(set! c h))))
(f "me")
(f " me")
(a "possible")
(d "impossible")
(equal? a b) ; <==== Is it possible to compare these guys
(equal? c d) ; <==== to get #t in both cases?
在这两种情况下,我们都会得到两个不同的函数“实例”(即使捕获了不同的值),但都在源代码的同一位置声明。当然,获取这些函数主体的实际文本将解决问题,但 SO 上的其他答案表明这在 Racket 中是不可能的。有什么技巧可以帮到我吗?
编辑: 这不是关于函数理论上等价的问题。这完全是技术问题,而不是关于 Racket 在编译代码中的函数表示。所以它可以被重新表述,例如,通过以下方式:我可以从“用户”代码中获取一些例程的行号吗?我想这应该是可行的,因为 Racket 调试器以某种方式获得它。
【问题讨论】:
-
您是否在寻找 lambda 表达式的语义相等性?
-
@JonChesterfield 我认为更“轻量级”的变体。如果在两个不同的地方声明了两个相同的函数,则没有必要获取
#t。如果函数值在代码中的同一行和同一位置声明,则获得#t就足够了。 -
这可能是可以解决的。 Iirc 球拍用调试信息标记表达式,因此一种方法是解析它。除此之外我什么都没有,但至少你不需要符号证明系统:)
-
@JonChesterfield,是的,这完全是技术问题:) 顺便说一句,感谢您提供调试信息的提示!也许我可以深入研究一下。
-
“其他答案表明这在 Racket 中是不可能的。”这不仅在 Racket 中是不可能的,而且在 任何 turing 完整的编程语言中可证明是不可能的。无论如何,您尝试做的事情可能通过宏来实现,但这似乎是个坏主意。这对我来说是an XY problem 的强烈气味。