[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Why would anyone want opacity?

   Date: Wed, 01 May 1996 10:07:12 +0000
   From: William D Clinger <will@ccs.neu.edu>

   Aubrey Jaffer wrote:
   > If we make opacity a first-class datatype, then it can be applied when
   > desired, rather than thrust upon every closure, even when unwanted.

   If opacity can be conferred on a procedure only by explicit
   use of some source-language construct, then roughly half of
   all compiler optimizations become illegal.

The ubiquity of lambda in Scheme code warrants a source-language
construct just to specify opacity of closures.  Here is a way to do
this which is compatible with existing code and existing Scheme

 - syntax: lambda <formals> <documentation> <body>
     *Syntax:*  <Formals> should be a formal arguments list as
     described below, and <body> should be a sequence of one or more
     expressions.  <Documentation> is a string.

     *Semantics:*  A lambda expression evaluates to a procedure. ...

     The `advertised' form of lambda is distinguished from the
     `opaque' form by a string <documentation> between <formals> and
     <body>.  The <documentation> string and possibly other
     information is accessible from advertised procedures (see *Note
     Procedure Information); This information is not available for
     opaque procedures.  However, opaque procedures can be optimized
     more aggressivly by compilers.

     Procedures comprising a module interface should use the
     advertised form.

          (define add4
            (let ((x 4))
              (lambda (y) "adds 4 to the argument" (+ x y))))
          (add4 6)                    =>  10
	  (procedure-documentation add4)
				      =>  "adds 4 to the argument"

	  (define advertised-wrapper
	    (letrec ((internal-procedure (lambda (a1 a2) (+ a1 a2))))
	      (lambda (a1 a2)
		"This demonstrates how to advertise a procedure without
	   advertising the internal procedures"
		(internal-procedure a1 a2))))


To the "Definitions" section add:

   * `(define (<variable> <formals>) <documentation> <body>)'

     This syntax is not essential.  <Formals> should be either a
     sequence of zero or more variables, or a sequence of one or more
     variables followed by a space-delimited period and another
     variable (as in a lambda expression).  This form is equivalent to
          (define <variable>
            (lambda (<formals>) <documentation> <body>)).

   * `(define (<variable> . <formal>) <documentation> <body>)'

     This syntax is not essential.  <Formal> should be a single
     variable.  This form is equivalent to
          (define <variable>
            (lambda <formal> <documentation> <body>)).


Here is a procedure to kick-off a "Procedure Information" section:

 - syntax: procedure-documentation <procedure>

     If <procedure> is an advertised procedure, then return the
     <documentation> string with which <procedure> was closed; If
     <procedure> is an opaque procedure, then return #f.


These enhancements fit naturally into Scheme.

* A string between the <formals> and <body> has no effect on execution
  of a procedure.

* The use of such a string in a procedure as documentation is
  compatible with Common Lisp.

* The possibility of extraction of said documentation string from a
  procedure necessarily implies the procedure is not opaque.

* Inclusion of a documentation string in a procedure indicates that
  the writer wishes to communicate information to another; thus it
  makes sense to make other information about the procedure (like
  arity) available for that documented procedure.