gpt4 book ai didi

scheme - 我如何打开当前范围的 Racket REPL?

转载 作者:行者123 更新时间:2023-12-01 15:20:11 25 4
gpt4 key购买 nike

假设我有这样一个程序:

(define (foo x) 
(local
((define y (- x 1)))
(* x y)))
(foo 3)

我希望能够在第 3 行和第 4 行之间打开一个 REPL,这样我就可以通过执行任意语句来探索(并可能修改)x 和 y 的值。

要在 Ruby 中做到这一点,我会采用等效的程序:

def foo(x)   
lambda {
y = x - 1
x * y
}.call
end
puts (foo 3)

并通过添加对 pry 的调用来修改它,以便在我想要的地方给我一个范围很好的 repl:

require 'pry'
def foo(x)
lambda {
y = x - 1
binding.pry
x * y
}.call
end
puts (foo 3)

要在 js 中执行此操作,我会在 Firebug 下运行该程序并在第 4 行放置一个断点:

foo = function(x) {  
return (function(){
var y = x - 1;
return x * y;
})();
};
console.log(foo(3));

然后我可以在评估窗口中探索内容。

我能做些什么来在 Racket 中得到这个吗?我发现最接近的是 DrScheme 的调试器,但它只显示当前范围的所有值,据我所知,它不允许您在 REPL 中探索它们。

最佳答案

这不是在回答您最初的问题,而是对您关于自己制作的评论的回应。我认为这是一个非常有趣的想法,所以我对其进行了探索。我能弄清楚的是:

假设您希望它起作用:

(define top-x 10)
(define (f)
(for ([i 10])
(displayln i)
(when (= i 5)
(pry)))) ; <= drop into a REPL here, resume after exiting REPL

pry 动的第一次尝试:

(define (pry)
(let loop ()
(display "PRY> ")
(define x (read))
(unless (or (eof-object? x) (equal? x '(unquote exit)))
(pretty-print (eval x))
(loop))))

这似乎可行:

> (f)
0
1
2
PRY> (+ 10 10)
20
PRY> ,exit
3
4
>

但是尽管它允许你访问像 + 这样的 Racket 函数,你甚至不能访问像 top-x 这样的顶级变量:

> (f)
0
1
2
PRY> top-x
; top-x: undefined;
; cannot reference undefined identifier

here 所述,您可以通过授予 eval 对当前命名空间的访问权限来获取顶级内容.所以 pry 需要一个命名空间参数:

(define (pry ns)
(let loop ()
(display "PRY> ")
(define x (read))
(unless (or (eof-object? x) (equal? x '(unquote exit)))
(pretty-print (eval x ns)) ; <---
(loop))))

要获得该参数,您需要在调试文件中添加以下咒语:

(define-namespace-anchor a)                  ; <---
(define ns (namespace-anchor->namespace a)) ; <---
(define top-x 10)
(define (f)
(for ([i 5])
(displayln i)
(when (= i 2)
(pry ns)))) ; <---

现在 REPL 可以查看和更改 top-x:

> (f)
0
1
2
PRY> top-x
10
PRY> (set! top-x 20)
#<void>
PRY> top-x
20
PRY> ,exit
3
4
>

太棒了!但它不能改变局部变量,i:

> (f)
0
1
2
PRY> i
; i: undefined;
; cannot reference an identifier before its definition

射击。原因说明here .

You might imagine that even though eval cannot see the local bindings in broken-eval-formula, there must actually be a data structure mapping x to 2 and y to 3, and you would like a way to get that data structure. In fact, no such data structure exists; the compiler is free to replace every use of x with 2 at compile time, so that the local binding of x does not exist in any concrete sense at run-time. Even when variables cannot be eliminated by constant-folding, normally the names of the variables can be eliminated, and the data structures that hold local values do not resemble a mapping from names to values.

你可能会说,好吧,但那样的话......

DrRacket 如何提供调试器?

据我所知,DrRacket 通过在评估程序之前注释语法来做到这一点。来自 drracket/gui-debugger/annotator.rkt :

  ;; annotate-stx inserts annotations around each expression that introduces a
;; new scope: let, lambda, and function calls. These annotations reify the
;; call stack, and allows to list the current variable in scope, look up
;; their value, as well as change their value. The reified stack is accessed
;; via the CURRENT-CONTINUATION-MARKS using the key DEBUG-KEY

所以我认为如果您想解决这个问题,这将是一个起点。

关于scheme - 我如何打开当前范围的 Racket REPL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19876940/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com