guile的程序 - 球拍来源?

时间:2011-06-12 22:23:23

标签: macros scheme racket

球拍是否具有类似guile的程序源功能,例如:

  

(定义(加一x)(+ 1 x))
  (procedure-source plus-one) - > (引用(+ 1 x))

我正在尝试为初学者创建类似于调试工具的东西,在这些工具中,当他们在2htdp / universe中使用其行为时,他们可以看到对特定函数的部分或完整评估。所以我可以在这种情况下使用一个宏,除了在他们的程序中我仍然希望定义看起来像往常一样,所以我不能让它们首先引用它并稍后评估它,除非我重新定义定义......这可能还可以,但我很感激指出如何最好地做到这一点。

3 个答案:

答案 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