球拍是否具有类似guile的程序源功能,例如:
(定义(加一x)(+ 1 x))
(procedure-source plus-one) - > (引用(+ 1 x))
我正在尝试为初学者创建类似于调试工具的东西,在这些工具中,当他们在2htdp / universe中使用其行为时,他们可以看到对特定函数的部分或完整评估。所以我可以在这种情况下使用一个宏,除了在他们的程序中我仍然希望定义看起来像往常一样,所以我不能让它们首先引用它并稍后评估它,除非我重新定义定义......这可能还可以,但我很感激指出如何最好地做到这一点。
答案 0 :(得分:1)
我做过这样的事情:
(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))
(有些肉遗失了,只是提出了一个想法。)如图所示,它不是超级健壮,但这是你倾向的方向吗?
答案 1 :(得分:1)
您遇到的问题是由于初学者学生语言限制:通常,高阶函数是语言中的语法错误,因为初学者还不应该知道它们。
有一种方法可以选择退出。您可以使用provide-higher-order-primitive将此过程源标记为此限制的例外之一,{{3}}专门用于与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。
答案 2 :(得分:0)
这就是我最终的结果:
(提供(重命名(定义/保存源定义))procedure-source)
然后在身体
(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))))
并在repl中:
> (define/save-source (plus-one x) (+ 1 x))
> (procedure-source plus-one)
(λ (x) (+ 1 x))
> (plus-one 3)
4
>
奇怪的是,在学生代表中,我得到了:
> (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