guile的程序源代码在racket中?

发布于 2024-11-15 03:09:07 字数 320 浏览 1 评论 0原文

racket 是否有类似 guile 的 procedure-source 功能,例如:

(定义(加一x)(+ 1 x))
(程序-来源加一) --> (引用(+ 1 x))

我正在尝试为初学者制作类似于调试工具的东西,他们可以在 2htdp/universe 中玩弄特定函数的行为时看到对特定函数的部分或完整评估。所以我可以在这种情况下使用宏,除了在他们的程序中我仍然希望定义看起来和平常一样,所以我不能让他们首先引用它并稍后评估它,除非我重新定义定义...这可能没问题,但我希望得到关于如何最好地做到这一点的指示。

Does racket have something like guile's procedure-source function, e.g.:

(define (plus-one x) (+ 1 x))
(procedure-source plus-one) --> (quote (+ 1 x))

I'm trying to make something akin to a debugging tool for beginning students, in which they can see partial or complete evaluations of a particular function while they play with its behavior in a 2htdp/universe. So I could use a macro for this case, except in their program I'd still like the definition to look exactly as usual, so I can't just have them quote it in the first place and eval it later, unless I redefine define... which might be okay, but I'd appreciate pointers on how best to do it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

权谋诡计 2024-11-22 03:09:07

您遇到的问题是由于初学者语言限制造成的:通常,高阶函数是该语言中的语法错误,因为初学者还不应该了解它们。

有一种方法可以选择退出。通过使用 provide-higher-order-primitive,专门用于配合BSL。

下面是您的库的外观:

#lang racket/base
(require lang/prim
         racket/bool
         (for-syntax racket/base))

(provide define/save-source)
(provide-higher-order-primitive procedure-name (fn))
(provide-higher-order-primitive procedure-source (fn))


(define *procedure-name-hash* (make-hash))  
(define *procedure-source-hash* (make-hash))  
(define (save-source! fn name body)  
   (hash-set! *procedure-name-hash* fn name)
   (hash-set! *procedure-source-hash* fn body))

(define (procedure-name fn)
  (hash-ref *procedure-name-hash* fn false))
(define (procedure-source fn)
  (hash-ref *procedure-source-hash* fn false))

(define-syntax define/save-source
  (syntax-rules ()
    ((_ (name formals ...) body-expressions ...)
     (begin
       (define name (λ(formals ...) body-expressions ...))
       (save-source! name 'name '(λ(formals ...) body-expressions ...))))
    ((_ name (λ(formals ...) body-expressions ...))
     (begin
       (define name (λ(formals ...) body-expressions ...))
       (save-source! name 'name '(λ(formals ...) body-expressions ...))))
    ((_ name value)
     (define name value))))

使用此库的 BSL 程序应该能够很好地使用 procedure-name 和 procedure-source。

The problem you're running into is due to a Beginner Student Language restriction: normally, higher-order functions are a syntactic error in the language, because beginners shouldn't know about them yet.

There's a way to opt-out of this. Your procedure-source can be labeled as one of the exceptions to this restriction, by using provide-higher-order-primitive, which is specifically meant to cooperate with BSL.

Here's what your library looks like with it:

#lang racket/base
(require lang/prim
         racket/bool
         (for-syntax racket/base))

(provide define/save-source)
(provide-higher-order-primitive procedure-name (fn))
(provide-higher-order-primitive procedure-source (fn))


(define *procedure-name-hash* (make-hash))  
(define *procedure-source-hash* (make-hash))  
(define (save-source! fn name body)  
   (hash-set! *procedure-name-hash* fn name)
   (hash-set! *procedure-source-hash* fn body))

(define (procedure-name fn)
  (hash-ref *procedure-name-hash* fn false))
(define (procedure-source fn)
  (hash-ref *procedure-source-hash* fn false))

(define-syntax define/save-source
  (syntax-rules ()
    ((_ (name formals ...) body-expressions ...)
     (begin
       (define name (λ(formals ...) body-expressions ...))
       (save-source! name 'name '(λ(formals ...) body-expressions ...))))
    ((_ name (λ(formals ...) body-expressions ...))
     (begin
       (define name (λ(formals ...) body-expressions ...))
       (save-source! name 'name '(λ(formals ...) body-expressions ...))))
    ((_ name value)
     (define name value))))

BSL programs that use this should be able to use procedure-name and procedure-source fine.

李不 2024-11-22 03:09:07

我做了这样的事情:(

(provide (rename-out (def/help define)
                     (define-syntax/help define-syntax))
         help)

(define-syntax def/help
  (syntax-rules ()
    ((_ name description signature (λ(vs ...) exps ...))
     (begin
       (add-help! 'name description 'signature '(λ(vs ...)))
       (define name (λ(vs ...) exps ...))))))
...
> (require "working.ss")
> (define (plus a b) (+ a b))
X define: bad syntax in: (define (plus a b) (+ a b))
> (define plus
    "Add two numbers"
    (int int -> int)
    (λ(a b) (+ a b)))
> (help plus)
plus
Add two numbers
(int int -> int)
(λ (a b))

缺少一些肉,仅提供一个想法。)它并不像所示的那么强大,但这就是您倾斜的方向吗?

I've done something like this:

(provide (rename-out (def/help define)
                     (define-syntax/help define-syntax))
         help)

(define-syntax def/help
  (syntax-rules ()
    ((_ name description signature (λ(vs ...) exps ...))
     (begin
       (add-help! 'name description 'signature '(λ(vs ...)))
       (define name (λ(vs ...) exps ...))))))
...
> (require "working.ss")
> (define (plus a b) (+ a b))
X define: bad syntax in: (define (plus a b) (+ a b))
> (define plus
    "Add two numbers"
    (int int -> int)
    (λ(a b) (+ a b)))
> (help plus)
plus
Add two numbers
(int int -> int)
(λ (a b))

(Some meat is missing, only giving an idea.) It's not super robust as shown but is this the direction you are leaning?

倦话 2024-11-22 03:09:07

这就是我最终得到的结果:

(提供(重命名(定义/保存源定义))过程源)

then in the body

(define *procedure-name-hash* (make-hash))  
(define *procedure-source-hash* (make-hash))  
(define (save-source! fn name body)  
   (hash-set! *procedure-name-hash* fn name)
   (hash-set! *procedure-source-hash* fn body))

(define (procedure-name fn)
  (hash-ref *procedure-name-hash* fn false))
(define (procedure-source fn)
  (hash-ref *procedure-source-hash* fn false))

(define-syntax define/save-source
  (syntax-rules ()
    ((_ (name formals ...) body-expressions ...)
     (begin
       (define name (λ(formals ...) body-expressions ...))
       (save-source! name 'name '(λ(formals ...) body-expressions ...))))
    ((_ name (λ(formals ...) body-expressions ...))
     (begin
       (define name (λ(formals ...) body-expressions ...))
       (save-source! name 'name '(λ(formals ...) body-expressions ...))))
    ((_ name value)
     (define name value))))

and in the repl:

> (define/save-source (plus-one x) (+ 1 x))
> (procedure-source plus-one)
(λ (x) (+ 1 x))
> (plus-one 3)
4
> 

奇怪的是在学生 repl 中我得到:

> (procedure-source update-target)
(cons 'λ (cons (cons 'x empty) (cons (cons '+ (cons 'x (cons 20 empty))) empty)))
> (update-target 30)
function call: expected a defined function name or a primitive operation name after an open parenthesis, but found something else

This is what I ended up with:

(provide (rename-out (define/save-source define)) procedure-source)

then in the body

(define *procedure-name-hash* (make-hash))  
(define *procedure-source-hash* (make-hash))  
(define (save-source! fn name body)  
   (hash-set! *procedure-name-hash* fn name)
   (hash-set! *procedure-source-hash* fn body))

(define (procedure-name fn)
  (hash-ref *procedure-name-hash* fn false))
(define (procedure-source fn)
  (hash-ref *procedure-source-hash* fn false))

(define-syntax define/save-source
  (syntax-rules ()
    ((_ (name formals ...) body-expressions ...)
     (begin
       (define name (λ(formals ...) body-expressions ...))
       (save-source! name 'name '(λ(formals ...) body-expressions ...))))
    ((_ name (λ(formals ...) body-expressions ...))
     (begin
       (define name (λ(formals ...) body-expressions ...))
       (save-source! name 'name '(λ(formals ...) body-expressions ...))))
    ((_ name value)
     (define name value))))

and in the repl:

> (define/save-source (plus-one x) (+ 1 x))
> (procedure-source plus-one)
(λ (x) (+ 1 x))
> (plus-one 3)
4
> 

What's odd is that in the student repl I get:

> (procedure-source update-target)
(cons 'λ (cons (cons 'x empty) (cons (cons '+ (cons 'x (cons 20 empty))) empty)))
> (update-target 30)
function call: expected a defined function name or a primitive operation name after an open parenthesis, but found something else
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文