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

Re: macros vs. blocks





> > 	(collect [(a b) | (< a b)] (cart-product as bs))
>
> Here you want a language implementation that contains the
> kind of optimizations that a good APL compiler would
> have, no?

Yes, but I'll handwave and say they're
simple for the sort of implementation
that breakfasts on left-left-lambdas.

Somewhere in collect (which otherwise
maps an empty list to an empty list)
will be the fragment:

	((lambda (l ls)
		(cond ((f l) (cons l acc))
		      (else          acc)))
	  uncons(list))

and here f is known statically:

	    ... (cond (((lambda (a b) (< a b)) unpair(l)) (cons ...
		      
Now, for control flow, we notice that
as a return of a call is a jump, which
cancels out the stack effect (but will
change the locus of control), so a
call of a return of a call is just a
single call.  For data flow, we see
that the cons of an uncons of a cons
can be collapsed into a single cons,
which cancels out a heap effect (but
will change the value in the list).

So if we expand cart-product into the
expansion of that collect call, we can
turn cart-product's:
	(cons (pair a b) acc)
into:
	((lambda (list)
		((lambda (l ls) ...)
		uncons(list)))
	 (cons (pair a b) acc))
or:
	((lambda (term acc)
		(cond ((lambda ...) unpair(term)) (cons term acc))
		      (else                                  acc))
	  (pair a b) acc)
or even:
	(cond ((< a b) (cons (pair a b) acc))
	      (else                     acc))

-Dave

(Languages like APL try to stream work-
in-progress past several stations instead
of blindly consing onto inventory between
each operation.  Should we call systems
which stream easily "kanban" systems?)