[m-users.] Mode error when working with hash_table

Zoltan Somogyi zoltan.somogyi at runbox.com
Sun Aug 30 23:43:08 AEST 2020

2020-08-30 22:51 GMT+10:00 "Ted Stock" <testock at gmail.com>:

>    24	:- func init(hash_pred(K)) = trie(K, V).
>    25	
>    26	%----------------------------------------------------------------------------%
>    27	%----------------------------------------------------------------------------%
>    28	
>    29	:- implementation.
>    30	
>    31	:- import_module maybe.
>    32	%----------------------------------------------------------------------------%
>    33	
>    34	:- type trie(K, V)
>    35	   ---> trie_(
>    36	                hash    :: hash_table.hash_pred(K),
>    37	                value   :: maybe(V),
>    38	                node    :: hash_table(K, trie(K,V))
>    39	        ).
>    40	
>    41	init(HashPred) = trie_(HashPred, no, hash_table.init_default(HashPred)).
>    42	
>    43	%----------------------------------------------------------------------------%
>    44	:- end_module trie.
>    45	%----------------------------------------------------------------------------%
> trie.err:
> trie.m:041: In clause for `init(in) = out':
> trie.m:041:   mode error in conjunction. The next 2 error messages indicate
> trie.m:041:   possible causes of this error.
> trie.m:041:
> trie.m:041:   In clause for `init(in) = out':
> trie.m:041:   in argument 1 of call to function `hash_table.init_default'/1:
> trie.m:041:   mode error: variable `HashPred' has instantiatedness `ground',
> trie.m:041:   expected instantiatedness was
> trie.m:041:     named inst hash_table.hash_pred,
> trie.m:041:     which expands to
> trie.m:041:       (pred(in, out) is det).

This error message tells you exactly what the error is. To understand it, please read
section 8.3 of the language reference manual.

Basically, whenever you pass a higher order value such as HashPred, telling the compiler
that it is input (or letting the compiler assume this because HashPred is a function argument)
is not enough: you also have to tell the compiler the modes of the predicate's arguments.
Since you have not specified any mode for your init function, you have not done this.
The compiler is pointing this out.

For an example of how to do this, see the declaration of the init function in hash_table.m
in the standard library.

> Second question,  how does hash_table.init_default know what type to make the hash_table?  default_init(K) takes a type K, but what about type V?  How does the compiler know what type to assign to V?

It infers that information from the context of its use. But the code manipulating
the hash table itself does not need to know what type V stands for, since it never looks
inside values. It does move them around, but it does not need to know the type for that.

> Third question (unrelated): I think that it would be helpful if there were an advanced online course for Mercury on one of the big MOOC sites like Udemy or Coursera.  It is quite an undertaking, but my understanding is that many of the project staff are former academics, so it would probably be like recording a semester of lectures.

You are right: it is quite an undertaking. I would be surprised if the cost were significantly
below fifty thousand dollars, but double or triple that wouldn't surprise me.
So far, noone has offered us that kind of money for a MOOC.

The papers section of mercurylang.org contains lecture notes for the "introduction to Mercury"
segment of (two different versions of)  a "taster" subject. That is not what you asked for,
but it should be useful.


More information about the users mailing list