Reginald Meeson <[EMAIL PROTECTED]> asks:
| This issue isn't really one of language definition, though. It seems
| to me it's an issue for programming support environments. I don't
| know of any language standard that includes requirements for
| debugging tools. Any implementers willing to give this a whirl?
As a matter of fact, Gofer has a (fully polymorphic) function
show' :: a -> String
that can be used to obtain printable representations of functions.
It's used mainly at the top-level of the evaluator; only Strings
and Dialogues can actually be handled directly, so if you enter a
value with some other type, for example, an integer, then show'
is automatically applied to obtain a string representation.
Actually, show' is even more impure because it can sometimes
recover after hitting bottom. For example:
? (3/0, 12)
({primDivInt 3 0},12)
Printing functions and printing bottom like this do seem to be quite
useful for debugging purposes, although they can also cause a little
confusion if you don't realize what's going on.
If uses of show' were restricted to the top-level, then the problems
that it could cause would be very limited, rather like the comments
somebody made about having a ShowFun request.
However, partly because Gofer doesn't have derived instances, and partly
because I wanted to make performance comparisons between overloaded and
non-overloaded implementations of show (BTW, the overloaded versions
were faster :-), the Gofer standard prelude also provides access to show'.
But I would caution very strongly against using the strings that it produces
to try and infer things about the original function. As others have already
said -- that's a fast route to big problems.
If you really want to manipulate some concrete representation of function
values, the best thing to do is to create an explicit concrete
representation. As a simple example, some functions of type Int -> Int
can be represented using:
> data FunctionOfN = N | Const Int | Sum FunctionOfN FunctionOfN
It's easy to manipulate these things in certain ways:
> constFold (Sum a b) = case (constFold a, constFold b) of
> (Const u, Const v) -> Const (u+v)
> (a', b') -> Sum a' b'
> constFold other = other
For example:
? constFold (Sum (Sum N (Const 1)) (Sum (Const 3) (Const 4)))
Sum (Sum N (Const 1)) (Const 7)
In a similar way, you can print, read and store these representations in a
standard, portable manner.
Now if you want the functions themselves, not their representations, then
you just write a simple `interpreter':
> interp :: FunctionOfN -> (Int -> Int)
> interp N = \n -> n
> interp (Const m) = \n -> m
> interp (Sum x y) = \n -> interp x n + interp y n
For example:
? interp (Sum (Sum N N) (Const 1))
v136 (Sum N N) (Const 1)
? interp (Sum (Sum N N) (Const 1)) 12
25
(Thought I'd include the first one as an example of show'ing a function).
Mark