[m-dev.] Re: conversion to univ twice

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Nov 10 22:57:25 AEDT 2000


On 10-Nov-2000, Peter Ross <peter.ross at miscrit.be> wrote:
> On Fri, Nov 10, 2000 at 09:41:47PM +1100, Fergus Henderson wrote:
> > On 10-Nov-2000, Peter Ross <peter.ross at miscrit.be> wrote:
> > > 
> > > The following program calls type_to_univ twice and then crashes when
> > > attempting to convert to the term representation.
> > > 
> > > What should happen is the second type_to_univ operation should be a no-op.
> > 
> > No, that's not what should happen.  That would break the invariant
> > that you can convert a value of any type to univ and then back again
> > (since it would fail if the value itself had type univ).
>
> I am not sure whether or not this invariant is useful for the univ case.
> 
> Can you give a good example of when you would want to convert a univ to
> a univ?

Well, suppose you have some general library that handles any type;
and suppose that internally, this library uses `univ'.
Now suppose I come along and pass a `univ' to this library.

An example of this is deconstructing values.
Suppose I have a value, and I want to get a list of its arguments.
Then I use std_util__deconstruct.  This returns a list of univs.

Now, suppose I have a type `:- type foo ---> f(int, univ, univ, string).'.
Some of the arguments of this type are univs.  So if I call
std_util__deconstruct, it needs to convert univs to univ.

Next, suppose I pass this type to `io__write' or something similar that
needs to deconstruct the value and perhaps serialize it.
To find out the types of the arguments of that constructor, all I
need to do is to call univ_type/1 on those univs return from
std_util__deconstruct, right?

If your suggestion was applied, then that would be wrong,
since the type of some of the arguments might be `univ',
but `univ_to_type' applied to the univs returned from `deconstruct'
would return the type contained in the univ, not `univ'.
Your suggestion would make it impossible to implement a version of
`io__write' whose output was valid Mercury code, since you wouldn't
know which arguments to wrap with `univ(...)'.

> I would imagine that most programmers would only do it on
> accident as shown by this bit of code
> 
> p :-
>     throw("a string").
> 
> q :-
>     call p with try block,
>     (
>         Result = exception(E),
>         throw(E)    % the univ not the string

The exception library provides a `rethrow' operation for precisely this.

> r :-
>     call q with try block
>     (
>         Result = exception(E),  % E is univ(univ(string)) not what was expected
> 
> And tracking down this bug was a bastard,

Well, that's unfortunate.  (Is there any particular reason why it was
so hard to track down?)

But at least it is very easy to fix once you know what the problem is.

In contrast, if we make univ handle nested univs specially, and you
need a univ that treats nested univs normally, any problems that result
will be much more difficult to fix.

> which is the motivation why I
> think that it being a no-op is a valid design choice.

If it's any consolation, Microsoft chose that approach for their
"typed reference" type (which is like our `univ' type).
I happen to think that they made a really bad decision on that one,
and have made this known to them...  but since the "typed reference"
type comes from the Visual Basic group, I didn't think it was worth
the effort of pushing hard on that issue.  (The problem is not as bad
their case since you can generally use System.Object as an alternative
to typed references.)

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list