[m-users.] newbe tutorial on development workflow and debugging

Zoltan Somogyi zoltan.somogyi at runbox.com
Wed Jul 3 10:32:39 AEST 2019



> A related technique that I enjoy
> is debugging by specifying: if your program doesn't behave as you
> expect, then make your code more precise until it starts to fail in
> more understandable ways. For example if you have a networking library
> that treats all file descriptors the same, then by giving server
> sockets and client sockets their own distinct types you might discover
> that some code has them misused.

We use this technique extensively in the Mercury compiler.
For example, program variables and type variables have distinct types
inside the compiler. Because these distinct types are different instances
of the same type constructor (var(prog_var_type) and var(tvar_type) respectively),
we can still use the same code to perform operations on both of them.

> there's just not as convenient a way to do it. What I'd like is an
> assert goal that doesn't effect determinism and that can be disabled
> with compile-time flags.
> 
>    some_pred(In1, In2, Out1, Out2) :-
>        assert In1 < In2,
>        assert ( In1 < Out1, In2 < Out2 ),
>        assert probably_prime(Out2),
>        normal_code.
> 
> Doable with trace goals. But how neatly?

Obviously, this is a question of taste, but to my mind, code such as

        trace [compiletime(flag("tree234_sanity_checks"))] (
            expect(unify(LeftOver, []), $pred, "leftovers")
        )

is neat enough. (That is a real example from the Mercury standard library.)

Zoltan.


More information about the users mailing list