[plt-scheme] Graphical snips and external dependencies?

From: Danny Yoo (dyoo at hkn.eecs.berkeley.edu)
Date: Fri Dec 29 00:06:39 EST 2006

Hi everyone,

I've been starting to do some investigation into bug 7001 (with related 
bugs 7317 and 7373) which have to deal with using Test Case boxes in 
modules.

In the HTDP and Pretty Big languages, there's some private code in its 
tool.ss that provides the context necessary for Test Case Boxes to work. 
However, in a module, that context is usually missing.  The current 
workaround, according to commentary in bug 7001, is to manually require 
test-case.ss.

This is a widespread issue with most of the interesting special snips. In 
the concrete case of test-case snips, it requires the enclosing context to 
import (lib "test-case.ss" "test-suite" "private"), and for GuiBuilder, 
(lib "class.ss").


I've been able to artificially inject the test-suite requirements by 
applying the attached diff (test-case-box.ss.diff).  However, I'm thinking 
this is totally the wrong solution.


I'm been thinking about this problem because it will probably affect my 
master's thesis work in developing an interesting DrScheme tool.  The 
current state of how snips expand out to syntax feels like there is 
something missing.  Has there been more consideration on redesigning the 
DrScheme snip interface to make more easily cooperate with modules and 
external dependencies?


I had thought about introducing some kind of special library snip form 
that cooperated with other snips.  The idea would be something like:

    (module test mzscheme
      (require (lib "snip-requires.ss"))

      << test box here >>
      ))

where there's some machinery that allows each snip to inform itself to 
snip-requires.ss, so that an import to snip-requires.ss pulls in the 
necessary requires in a way that respects lexical scope.  Later on, when a 
snip expands out into syntax, it should be able to refer lexically to the 
provided symbols from that (require (lib "snip-requires.ss")) form.

That is, I'd like to be able to say:

    (module test mzscheme
       (require (lib "snip-requires.ss"))

       (define test-case 42)

       << test box here >>
    )

where my local definition of TEST-CASE would NOT conflict with the one 
provided by snip-requires.ss, and where everything works out.  I guess I'm 
chasing after a way of making snips work hygienically when they expand to 
syntax.

I'm planning to play around with this to see how far I get, but does this 
seem like a plausible solution that'd work, or are there problems here 
too?


Thanks again!
-------------- next part --------------
Index: private/test-case-box.ss
===================================================================
--- private/test-case-box.ss	(revision 5065)
+++ private/test-case-box.ss	(working copy)
@@ -98,7 +98,7 @@
 			  (with-syntax ([exn-pred-stx (text->syntax-object should-raise #'exn:fail?)]
 					[exn-handler-stx
 					 (if (empty-text? error-message)
-					     #'(lambda (v) true)
+                                             #'(lambda (v) #t)
 					     #`(lambda (v)
 						 (equal? (exn-message v)
 							 #,(text->syntax-object
@@ -106,23 +106,27 @@
 							    #f))))])
 			    (syntax/loc (datum->syntax-object
 					 false 'ignored (list source line column position 1))
-			      (test-error-case to-test-stx
-					       exn-pred-stx
-					       exn-handler-stx
-					       update-stx
-					       set-actuals-stx)))
+                              (begin
+                                (require (lib "test-case.ss" "test-suite" "private"))
+                                (test-error-case to-test-stx
+                                                 exn-pred-stx
+                                                 exn-handler-stx
+                                                 update-stx
+                                                 set-actuals-stx))))
 			  (with-syntax ([exp-stx (text->syntax-object expected #f)]
 					[pred-stx (text->syntax-object predicate beginner-equal?)])
 			    (syntax/loc (datum->syntax-object
 					 false 'ignored (list source line column position 1))
-			      (test-case pred-stx
-					 to-test-stx
-					 exp-stx
-					 update-stx
-					 set-actuals-stx)))))
+                              (begin
+                                (require (lib "test-case.ss" "test-suite" "private"))
+                                (test-case pred-stx
+                                           to-test-stx
+                                           exp-stx
+                                           update-stx
+                                           set-actuals-stx))))))
 		    (stepper-syntax-property #'(define-values () (values))
-                                            'stepper-skip-completely
-                                            true))
+                                             'stepper-skip-completely
+                                             true))
 		'test-case-box #t)))
            
            #;(boolean? . -> . void?)

Posted on the users mailing list.