Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

guile's procedure-source in racket?

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.

like image 592
Gregory Marton Avatar asked Dec 20 '25 22:12

Gregory Marton


1 Answers

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.

like image 173
dyoo Avatar answered Dec 24 '25 11:12

dyoo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!