mark at mercurylang.org
Tue Sep 16 10:47:26 AEST 2014
On Mon, Sep 15, 2014 at 4:23 PM, Mark Brown <mark at mercurylang.org> wrote:
> On Mon, Sep 15, 2014 at 3:46 PM, Peter Wang <novalazy at gmail.com> wrote:
>> Hi Mark,
>> On Sun, 14 Sep 2014 12:51:44 +1000, Mark Brown <mark at mercurylang.org> wrote:
>>> This is much more verbose than Peter's suggestion, but aside from the
>>> better checking it's also much more flexible because you can target
>>> different libraries, not just different versions of the same library.
>>> For example, if there is a module called fastlib that only some
>>> developers have in their path, you might write:
>>> :- pred algorithm(int::in, int::out) is det,
>>> :- if.
>>> :- import_module fastlib. % This can fail.
>>> :- pred fastlib.algorithm(int::in, int::out) is det.
>>> :- then.
>>> algorithm(X, Y) :- fastlib.algorithm(X, Y).
>>> :- else.
>>> algorithm(X, Y) :- slow_algorithm(X, Y).
>>> :- end_if.
>>> Note that, even though fastlib is imported, we still have to declare
>>> the predicates from it that are used. This enables the then branch to
>>> be checked even if the import fails, and also allows a check that
>>> fastlib itself is the right version.
>> I like it.
>> Is it fair to think of each if-then branch declaring something like an
>> anonymous nested sub-module, with forwarding of predicates and types
>> from the parent module to the sub-module?
> Exactly. That was the motivation for the syntax, too.
For good measure, here is an alternative syntax. This time the
branches are written in the style of nested sub-modules, but the
conditions are written in the style of typeclass definitions. I think
I prefer this, because satisfying these conditions is quite like
satisfying the conditions of a typeclass.
:- pred algorithm(int::in, int::out) is det.
:- if [
pred fastlib.algorithm(int::in, int::out) is det
algorithm(X, Y) :- fastlib.algorithm(X, Y).
algorithm(X, Y) :- slow_algorithm(X, Y).
More information about the developers