[m-dev.] collect

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Jun 25 16:10:03 AEST 1999


On 24-Jun-1999, Erwan Jahier <Erwan.Jahier at irisa.fr> wrote:
> Fergus wrote:
> | Another drawback is the need for the user to learn two languages:
> | as well as knowing Mercury, they also need to learn the Prolog-based
> | Opium-M command language.
> 
> Well, Ok but:
> 
> 1) Opium-M command language is nothing more than Prolog + 2 primitives that
> manipulate the trace (current/1 and fget/1), which is not such a big step for
> Mercury programmers.

Well, I'm not so sure about that.  Prolog has lots of stuff like cut,
repeat-fail loops, side effecting I/O, etc. which will be new to
Mercury programmers who don't know Prolog.
And fget/1 uses side effects, and failure-driven loops seem to be a
commonly used paradigm in Opium-M code, so they really can't just
ignore these things.

> 2) End-users don't need to know Prolog to use Opium-M the same way as they
> don't need to know Lisp to use emacs.

Sure.  But they don't need to know Prolog to use the Mercury internal
debugger either.  The question is about how to provide a programmable
interface.

> 3) [...]
> We strongly think that a Prolog interpreter is the most suitable to type
> queries on the fly. Of course, when writing Opium-M commands that are real
> programs, then being able to write it in Mercury would be very nice, but it 
> would lead to something a bit heterogeneous.
> 
> Of cource, if we had a Mercury commands interpreter that is as convenient as
> the eclipse one to type queries on the fly, then things would be quite
> different and Mercury might be the best candidate for the 3 debuggers. But
> I am not convinced the Mercury semantics will let you get that.

I don't think the semantics are a problem at all.
The current implementation technology is the problem.
If we had a Hugs-like implementation of Mercury, then I think you
would be convinced.

Of course, currently we don't have a Hugs-like implementation of Mercury,
and so that leaves the question of what to do in the meantime.

> | The paper skimmed over a few things -- I'd like to know more of the details.
> | For example, the interface to `collect' is not entirely clear -- what are
> | the types of the arguments?
> 
> Do you mean the type `event' ? (the only other argument type is collected_type
> which defined by users so...)

I meant the interface to `collect', not the interface to `filter'.

> You will soon be able to get a few more details since I am about to submit a 
> diff that implements what is described in the paper.

Great.

> | It might be more elegant if the dynamically linked module defined a single
> | function returning an instance of a standard typeclass, rather than defining
> | a type and two specific predicates acting on that type, with specific
> | argument types, modes and determinism.  
> 
> The 2 predicates always have the same type, mode and determinim i.e.:
> 
> :- pred initialize(collected_type::out) is det.
> :- pred filter(event::in, collected_type::in, collected_type::out) is det.
> 
> The only things the user needs to write is:
> - the type of the collecting variable
> - the body of initialize/1 
> - the body of filter/3

What happens if the user accidentally writes

    :- pred filter(collected_type::in, event::in, collected_type::out) is det.

instead of

    :- pred filter(event::in, collected_type::in, collected_type::out) is det.

?
I suspect the answer in your current implementation is "undefined behaviour",
probably a seg fault.

> Note that I could have let the collecting variable uninstanciated:
> 
> :- pred initialize(T) .
> :- pred filter(event, T, T).

No, that wouldn't work, because the type variables there are implicitly
universally quantified

	:- all [T] pred initialize(T) .
	:- all [T] pred filter(event, T, T).

but the bodies of the `initialize' and `filter' predicates will only
work with one particular type T, not with all types T.  If you declared
`initialize' and `filter' in this way, then you would get a type error
when compiling the definitions of those predicates.

Simply replacing the universal quantifiers with existential quantifiers
doesn't work either, because that doesn't capture that requirement that
the type `T' in `initialize' be the same as the type `T' in `filter'.
You need to make `initialize' also return the filter predicate, so that
you can get a single existential quantifier to scope over both occurrences
to the type `T':

	:- some [T] pred initialize(T, pred(event, T, T)).

What I proposed is basically the same as this, except that I used
a type class rather than returning a higher-order predicate term.

> In which sense do you say it is more elegant?

Well, I said it _might_ be more elegant.

Any errors in the interface will not be caught by the compiler, I
believe, so it seems like a good idea to keep the interface as small
and as simple as possible.
With the typeclass version, the interface is smaller -- just one function,
rather than a type and two predicates.  On the other hand, with the typeclass
version the interface is arguably more complex, since it uses typeclasses
(or higher-order predicates) and existential types.

The typeclass version makes it a little clearer that the module must
implement a particular interface, and provides better static checking
to ensure that the module does indeed actually implement that interface.
The static checking is still not perfect, since the interface of the
one function itself is not checked.

The extra static checking would help if you ever change the interface,
e.g. by adding a new parameter to the `filter' predicate, or adding
new predicates (e.g. one to handle the final result might well be
useful).

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- 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