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

Re: Dependency analysis on internal DEFINE's




	From: willc@tekchips.crl
	
	I guess I don't understand what is being proposed, because it doesn't 
	look computable to me.  Here are the proposals, followed by a couple 
	of examples that illustrate my lack of understanding.
	
	  [Tiedeman:]
	  This can also be made to work by having LETREC's implement an 
	  applicative order fixpoint rather than the restriction of it 
	  specified in R3RS.  This amounts to performing dependency analysis 
	  to transform the above into a LET*.  Alas, this requires static 
	  analysis which an interpreter can't afford.  Some compilers, however,
	  already do it.

I wasn't actually making a proposal, just using the idea for purposes of 
conceptual ellucidation.  However, I'd like to try to answer your questions.

I used the term "the applicative order fixpoint" because I think what I have 
in mind is the most general fixpoint allowed by applicative order evaluation 
(I could well be wrong.) and I'll continue to use it in describing what I 
meant.  I'll refer to the behavior specified in the report as a "R3RS 
fixpoint."

The only place I fault R3RS fixpoints is where they are used for LETREC's that 
don't involve mutual recursion among all the bindings.  Such LETREC's can be 
broken up into subsets of mutually recursive bindings (i.e. the condensation 
of the LETREC's dependency graph.)  These subsets can further be ordered by 
their interdependencies (by topologically sorting the condensation) and then 
implemented as nested LETREC's (or LET's when they have but one binding which 
is non-recursive.)  Since all the LETREC's now represent true recursions we 
can safely treat them as R3RS fixpoints.  This treatment of LETREC's is a 
generalization of R3RS fixpoints.

Here's an example of a applicative order fixpoint which R3RS wouldn't handle:

	(letrec ((x 2)
	         (y (+ x 2)))
	 ....)

which, by the above method, is the same as:

	(let ((x 2))
	 (let ((y (+ x 2)))
	  ....)

In both of your examples the DEFINE's are mutually recursive and so R3RS 
semantics would be followed.

Note, however...

	Example 2:
	
	  (let ((x '(a b c)))
	    (define y
	      (map (lambda (a) (cons a z)) x))
	    (define z
	      (map (lambda (a) (cons y a)) x))
	    (append y z))
	
	  This is not allowed by the wording in the R3RS.

According to R3RS this is "undefined, and an error may be signalled."  Is 
"undefined" defined in the report?  Presumably the wording was designed to 
leave room for the plethora of "compatible extensions" out there--sometimes 
more than one in the same implementation.  Ceteris paribus I would prefer that 
it were "an error."

	                                                            ...The
	thing I don't understand is how an "applicative order" fixed point can
	be a generalization of the current state of affairs while remaining
	computable through static analysis.

I hope I've made this clear.  Whether the applicative order fixpoint is
actually defined for any given LETREC is, of course, not computable.  You can,
however, always set it up in linear time.

Eric