[plt-scheme] Abstraction in require statements

From: Dave Gurnell (d.j.gurnell at gmail.com)
Date: Tue Sep 11 08:02:08 EDT 2007

Dear PLTers,

I'm looking for a bit more abstraction in require statements. I'm  
wondering if anyone knows of an existing solution or might be able to  
suggest an approach. Here's the problem:

Require forms can get a little verbose. Here is an example from a  
module in an Untyped web application:

     (require (planet "list.ss" ("untyped" "unlib.plt" 2))
              (planet "string.ss" ("untyped" "unlib.plt" 2))
              (only (planet "check.ss" "check" ("untyped" "unlib.plt"  
2)) pass fail warn))

Unlib is a significant library for this application - there are on 2  
to 3 Unlib-oriented require statements per module in around 100  
modules. I would like to abbreviate the require statements to make  
things more readable and easier to maintain.

Ryan Culpepper has a possible solution in his require.plt package:

     (require (planet "require.ss" ("ryanc" "require.plt" 1 3)))

     (define-library unlib
       (planet ("untyped" "untyped.plt" 2)))

     (require-unlib "list.ss" "string.ss")

     (require (only (planet "check.ss" "check" ("untyped" "unlib.plt"  
2)) pass fail warn))

In this example require.plt handles list.ss and string.ss very well,  
but it fails to deliver on check.ss because require-unlib is not  
composeable with only, all-except and so on.

I would like to be able to do something equivalent to:

     (define-syntax (unlib stx)
       (syntax-case stx ()
         [(unlib file)
          #'(planet file ("untyped" "unlib.plt" 2))]))

     (require (unlib "list.ss")
              (unlib "string.ss")
              (only (unlib "check.ss") pass fail warn))

Of course, this doesn't work because of the way require is  
implemented, but you get the idea.

I have thought about implementing a require* form that expanded into  
require:

     (define-require*-syntax unlib
       ; blah blah blah
       )

     (require* (unlib "list.ss")
               (unlib "string.ss")
               (only (unlib "check.ss") pass fail warn))

The idea would be to get define-require*-syntax to store its forms in  
some kind of private namespace, and get require* to search that  
namespace to retrieve the forms. That way, require* forms won't be  
defined in module bodies. Because require* expands into require,  
require* forms should only be able to expand into require forms.

Alas, my macro-fu is weak, and I don't know if this is a realistic  
approach. Also, it's not worth trying to implement something like  
this if there's an existing solution that does the job. Hence this  
email!

Cheers,

-- Dave



Posted on the users mailing list.