Re: C minus minus? No, C monad monad.

On Thu, Nov 03, 2005 at 12:57:54PM +0100, Christof Douma wrote:
It is nice to see GRIN is used by other people as well. My work has been to extend the GRIN model to be usefull for exceptions and implement a grin compiler. I am currently in the process of writing the results down.
I am glad to see other people using it too :) I have read some of your stuff and am looking forward to seeing the results.
Continuations in this example are not needed. The example calls some function by using continuations. The idea of GRIN is to have nodes which represent thunks. A partial application to some function foo can be represented by a node which describes which function to be called when fully saturated and the already applied arguments. The above example can be rewritten to standard GRIN as follows:
foo x = return (x + 4)
myfunc = \(a,b) -> do cont <- return (P1foo) //store a partial application node case (a - b) of 3 -> return -1 5 -> apply cont 2 z -> apply cont z
apply f a = case f of P1foo -> foo a
The problem is that this is the exact opposite transformation that I am trying to carry out :) The above is what is generated by my front-middle-end (hmm. need new terminology) and my goal is to transform it into explicit loops with updatable variables. These things cannot be expressed directly in traditional Grin which is why I introduced continuations and a series of transformations to turn the above into efficient looping updating c-- code.
yay! Grin has gained a whole lot of power from stealing this idea from c--. yay! Grin already has a whole lot of power. ;-)
Indeed, but the goal of jhc is to produce code that is faster than C code. any compromises in expressing algorithms that can be expressed in C are not ones I am willing to make :) so powerful here doesn't mean being able to do more. it means being able to express the optimizations I need to in order to produce code that runs as efficiently as I want without sacrificing Grin's nice theoretical properties.
Secondly. Modelling exceptions in GRIN does not benefit from the use of these continuation constructs. GRIN does not have some global variable in which you can store the exception handler. Of course this can also be added (as a primitive in the monad). But what is the difference to a global variable with a node in it?
Although jhc does not have global variables, it does have global names, this is how CAFs are implemented. theoretically, you can think of them as parameters that are implicitly passed to every function and they have the same semantics, but practically, I don't implement them that way of course. They are not special in any way and are just like any other grin name so none of the machinery needs to change to take them into account. in any case, one of these global names can easily hold the value of some heap location or register to store the exception stack. This is exactly what needs to be done to implement updatable CAFs properly so I am not adding any new concepts to support exceptions.
The extension I created allows exceptions in GRIN with the use of try catch and throw statements. These two are monad primitives. The try catch statments defines a continuation and pushes it on the exception handler stack. The throw statment cuts to that handler. Leaving the scope of the try statement or entering the handler will restore the previous handler.
Indeed, I was looking at using this model too, but I decided against it for a couple reasons, the main one is that continuations give me a whole lot of other advantages I can make good use of. but other than that, it means that the IO monad will have to be special since it has these primitives that are part of the monad. in jhc, the IO monad is exactly data World__ data IOResult a = FailIO World__ IOError | JustIO World__ a newtype IO a = IO (World__ -> IOResult a) with continuations as a primitive, I could get rid of FailIO and have the continuation actually be the World__ value that is passed around, this also incidentally obviates the need for a global variable as mentioned above. It also opens up the use of the continuation primitive to other uses, like a more efficient Control.Monad.Cont. though, imprecise exceptions most likely would need a global exception stack though I am still undecided as to whether those are a good idea.
Doing register allocation and instruction selection in GRIN sure looks nice. It is an intresting thought.
Yeah, I think boquist would have benefited from a lot of these ideas since he went directly from grin -> assembly. going through c or c-- affords us a lot more freedom. but using this algorithm to decide what goes in C local variables is quite useful too. John -- John Meacham - ⑆repetae.net⑆john⑈
participants (1)
-
John Meacham