Hello,

On Sat, Feb 16, 2013 at 2:14 PM, Mark H Weaver <mhw@netris.org> wrote:
Noah Lavine <noah.b.lavine@gmail.com> writes:
> Oh, you're right. I was thinking about that because I don't run the
> Tree-IL optimizers when I test it, so I don't get any Tree-IL
> primitives.

I think you should be running the existing tree-il passes before you
convert to CPS.  As I pointed out earlier, many optimizers will not be
able to work well after conversion to CPS, fundamentally because CPS
loses information about where order of evaluation is unspecified.

Furthermore, some of the existing passes make important simplifications
to the resulting tree-il.  For example, the code in fix-letrec.scm
eliminates all <letrec> nodes, so that's one less thing for you to have
to implement.  Primitives.scm marks primitives explicitly using
<primcall> tree-il nodes, so that later code doesn't have to make thorny
assumptions about what variables should be considered primitives.

Interesting points. I think you're right that Tree-IL should be optimized first. For the specific issue of order of evaluation, I'm hoping to add something (either a special function or a special node type) to CPS to represent continuations that can be evaluated in any order. It seems like evaluation order is a decision that should be made in either the code generator or the register allocator, and those operate on CPS. I also dislike losing information.
 
> I think I read that loading GOOPS turns things like '+ into generic
> operations - that might be a case where this matters a lot.

No, because GOOPS has a special mechanism for cases like '+': they are
called "primitive generics".  When numerical operations are unable to
handle the argument types provided, they calls 'scm_wta_dispatch_*'.
Therefore, adding new methods to numerical operations does not involve
changing their bindings.  This is good because it means that you can
extend numerical operations without slowing them down at all for
built-in numbers.

I see. That's very cool.
 

> I have thought a bit about how to fix this. The module system already
> allows us to be notified whenever a variable changes, so it would be
> easy to watch all of the variables in (guile) and recompile procedures
> when they change. I might take a look at this soon.

This would be nice too, of course, but I warn you that it's a can of
worms.  In the general case, it involves on-stack replacement, because
you might need to recompile a procedure that's currently in the middle
of being run, and thus currently has activation records on the stack(s).

You mean if a function modifies another function that called it. Yes, that seems complicated. It's not very important to me to fix it in general, because I don't know of a case where it's useful. I think fixing it without the on-stack replacement would be a reasonable compromise.
 
Thanks for you work on this, Noah!

Thank you!

Noah