help needed for adding isWHNF primop to 5.00.2

Bernard James POPE
Tue, 31 Jul 2001 13:36:50 +1000 (EST)

> | > I would like to add a primitive to GHC 5.00.2 of the form:
> | >
> | >    isWHNF :: a -> Bool
> One might be inclined to ask what for?  Such a primitive is
> probably difficult to implement, given the variety of GHC's
> closures, 

From reading the documentation that comes with GHC and glancing over the
source code, I came to these set of assumptions, please correct me if I am

- values of unpointed types are never in WHNF

- values of pointed types may be in WHNF, in particular:

     - data constructors are in WHNF
     - partial applications are in WHNF
     - functions are in WHNF
     - thunks are not in WHNF
       (this list is probably not exhaustive as you say, but I am happy
        with this set of definitions for the moment)

> and is potentially dangerous -- you could conceivably
> break referential transparency (?)  

With the type that I have specified above, yes, it is _very dangerous_
when used without caution. I do not intend for this feature to be
used widely in everyday programming. Its probably not terribly useful for
most tasks either.

> I can also imagine it
> could interact badly with the complexities of GHC's 
> simplifer.

This is something I do not know. In the end I may define it with this type:

   isWHNF :: a -> IO Bool 

as Simon Marlow suggested, indeed this was my original intention, but I am new 
to the internals of GHC and thought it might be easier to get the unsafe one 
working first. For my own purposes the unsafe version is what I want. 
However, the version in the IO monad looks more reasonable, and I can get
the unsafe version with unsafePerformIO, whilst maybe requiring some 
pragmas to help the simplifier out?

> What would you hope to gain from such a thing?  Perhaps
> you have some wider purpose which could be achieved some 
> other way?

I want it for the purposes of meta-programming, and also for debugging since
that is what I am working on. At the end of a computation (that results in
a value of pointed type, say) I want to know to what extent expressions were

      foo xs = take 3 xs

      ... foo [4..] ...

   debugger> foo [4,5,6,_ = [4,5,6]

Since I am inspecting things after the computation is complete, I should
be able to rely on the information from isWHNF.

I don't think that the scheme that HOOD uses is right for me, since 
the overheads would be too costly (I don't want to log every reduction in
my program just in case I might need to debug a branch of the
computation later on). 

If you like, what I am doing is a post-mortem inspection of (some) values 
generated by a program. This is quite standard for declarative debuggers
for non-strict languages.

I can do this in HUGS via the HugsInternals interface, and I think that it
is also possible in NHC too. 

I'm eager to hear you comments and suggestions, and I appreciate the
feedback that I have received so far.