# [mercury-users] Incomprehensible error output, even with -E.

Michael Richter ttmrichter at gmail.com
Thu Feb 2 16:13:54 AEDT 2012

```On 2 February 2012 13:01, Michael Richter <ttmrichter at gmail.com> wrote:

> On 2 February 2012 05:50, Julian Fondren <ayrnieu at gmail.com> wrote:
>
>> to make the problem clearer, you have here
>>
>>   A = (func(X) = B, C),
>>
>> How is this not like your definitions of named functions?
>>
>>
> It's got a lambda instead of a :- func body?
>
> Maybe I'm fundamentally misunderstanding the syntax of funcs vs. preds.
>  (There doesn't appear to be a grammar for Mercury in the language
> reference so I'm only inferring what's permitted and what's not.)
>
> Let's say I have a predicate like this:
>
> a(X,Y) :- Y = X.
>
> This is fine, right?  And the equivalent written as a function is this:
>
> a(X) = X.
>
> I know this is fine because I've just tested it.  The compiler doesn't
> vomit.  Now let's say that I want to do a calculation on X first.  Here
> it'll be a brain-dead calculation but the principle is the same whether
> it's something stupid like this or something that actually warrants
> breaking out the calculation into its own sub-step:
>
> a(X,Y) :- B = X * 2, Y = B.
>
> Again, the compiler doesn't puke on this and the result is as expected.
>  So the equivalent function is:
>
> a(X) = B = X * 2, B.
>
> Only that doesn't work because you get an operator precedence error on
> "=".  (It also looks pretty retarded.)  Time for plan B.
>
> a(X) = (B = X * 2, B).
>
> Whiiiiiiiiiiichâ€¦ gives me the error that's mystified me so long.  I may be
> on to something here!  Let me take another crack at it.  Looking at the
> library source I see another way that functions are defined.  Let me see if
> the same kind of structure helps here.
>
> a(X) = Y :- B = X * 2, Y = B.
>
> OK, that works.  So let's see how that looks in a lambda.
>
> A = (func(X) = Y :- B = X * 2, Y = B).
>
> OK, that seems to work, so let's make B a func as well:
>
>     A = (func(X) = Y :-
>             B = (func(X) = Y :-
>                     Y = X * 2
>                 ),
>             Y = B
>         ).
>
> Andâ€¦  Now I'm even more confused.  Yesterday when I tried that very
> structure I got lots of whining from the compiler about syntax errors on
> the :-. Damn.
>

Oops.  I spoke too soon.  I forgot to save the file before compiling.

This vomits up a whole bunch of garbage (the lambda in question starts on
line 19):

junk.m:019: In clause for predicate `junk.main'/2:
junk.m:019:   warning: variable `A' occurs only once in this scope.
junk.m:019: In clause for predicate `junk.main'/2:
junk.m:019:   warning: variable `X' occurs only once in this scope.
junk.m:020: In clause for predicate `junk.main'/2:
junk.m:020:   warning: variable `X' has overlapping scopes.
junk.m:023: In clause for predicate `main'/2:
junk.m:023:   type error in unification of variable `Y'
junk.m:023:   and variable `B'.
junk.m:023:   `Y' has type `int',
junk.m:023:   `B' has type `((func int) = int)'.
junk.m:023:   The partial type assignment was:
junk.m:023:     A_4: ((func V_1) = V_2)
junk.m:023:     Y_6: int
junk.m:023:     B_7: ((func int) = int)
junk.m:023:     STATE_VARIABLE_IO_0_8: io.state
junk.m:023:     STATE_VARIABLE_IO_9: io.state
junk.m:023:     V_10: V_1
junk.m:023:     V_11: V_2
junk.m:023:     V_12: int
junk.m:023:     V_13: int
junk.m:023:     V_14: int
junk.m:023:     X_17: V_1
junk.m:023:     X_18: int

One of the problems I see is that I'm returning B instead of calling it and
returning its value.  Let's change that:

A = (func(X) = Y :-
B = (func(X) = Y :-
Y = X * 2
),
Y = apply(B, X)
).

This gives me different consistencies of compiler vomit:

junk.m:019: In clause for predicate `junk.main'/2:
junk.m:019:   warning: variable `A' occurs only once in this scope.
junk.m:019: In clause for `main(di, uo)':
junk.m:019:   mode error in conjunction. The next 3 error messages indicate
junk.m:019:   possible causes of this error.
junk.m:020:   In clause for `main(di, uo)':
junk.m:020:   mode error: variable `Y' has instantiatedness `free',
junk.m:020:   expected instantiatedness for non-local variables of lambda
goals
junk.m:020:   is `ground'.
junk.m:023:   In clause for `main(di, uo)':
junk.m:023:   in argument 1 (i.e. the function term) of higher-order
function
junk.m:023:   call:
junk.m:023:   mode error: variable `B' has instantiatedness `free',
junk.m:023:   expecting higher-order func inst (of arity 1).
junk.m:019:   In clause for `main(di, uo)':
junk.m:019:   in argument 1 of clause head:
junk.m:019:   mode error in unification of `V_11' and `Y'.
junk.m:019:   Variable `V_11' has instantiatedness `free',
junk.m:019:   variable `Y' has instantiatedness `free'.
junk.m:020: In clause for predicate `junk.main'/2:
junk.m:020:   warning: variable `X' has overlapping scopes.

Hmmm....  Seems to be a clash of variable name scopes.  Maybe a some?

A = (func(X) = Y :-
some [X,Y] (
B = (func(X) = Y :-
Y = X * 2
)
),
Y = apply(B, X)
),

Eh.... no.  That tosses up lots as well:

junk.m:019: In clause for predicate `junk.main'/2:
junk.m:019:   warning: variable `A' occurs only once in this scope.
junk.m:019: In clause for `main(di, uo)':
junk.m:019:   mode error in conjunction. The next 3 error messages indicate
junk.m:019:   possible causes of this error.
junk.m:021:   In clause for `main(di, uo)':
junk.m:021:   mode error: variable `Y' has instantiatedness `free',
junk.m:021:   expected instantiatedness for non-local variables of lambda
goals
junk.m:021:   is `ground'.
junk.m:025:   In clause for `main(di, uo)':
junk.m:025:   in argument 1 (i.e. the function term) of higher-order
function
junk.m:025:   call:
junk.m:025:   mode error: variable `B' has instantiatedness `free',
junk.m:025:   expecting higher-order func inst (of arity 1).
junk.m:019:   In clause for `main(di, uo)':
junk.m:019:   in argument 1 of clause head:
junk.m:019:   mode error in unification of `V_11' and `Y'.
junk.m:019:   Variable `V_11' has instantiatedness `free',
junk.m:019:   variable `Y' has instantiatedness `free'.
junk.m:020: In clause for predicate `junk.main'/2:
junk.m:020:   warning: variables `X, Y' each have overlapping scopes.
junk.m:021: In clause for predicate `junk.main'/2:
junk.m:021:   warning: variable `X' has overlapping scopes.

And at this point I'm lost.  How does X have overlapping scope when I've
explicitly built a new scope for the second X?  Again I have to ask, how do
I do what I'm trying to do?  Equivalent code in almost any other language I
have that supports higher-order programming is trivial.  Why am I wrestling
so much with Mercury to do the same?  What am I missing?

--
"Perhaps people don't believe this, but throughout all of the discussions
of entering China our focus has really been what's best for the Chinese
people. It's not been about our revenue or profit or whatnot."
--Sergey Brin, demonstrating the emptiness of the "don't be evil" mantra.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20120202/3ea1b47c/attachment.html>
```