[m-users.] Problem with unique modes
Ricardo Correia
lists.mercurylang.org at wizy.org
Sun Jul 25 04:40:08 AEST 2021
Your answers were extremely clear, thank you!
On Sun, Jul 25, 2021 at 02:22:03AM +1000, Zoltan Somogyi wrote:
>
> 2021-07-23 11:27 GMT+10:00 "Ricardo Correia" <lists.mercurylang.org at wizy.org>:
> > However, I'm not entirely sure how to make type `state` unique.
>
> Due to limitation mentioned in the LIMITATIONS file, you can't.
>
> > Then, I tried to do what the `hash_table` standard library module does,
> > I think, by declaring an instantiation (?) and some custom `sdi` and
> > `suo` modes, because `hash_table` is also a type which has some integers
> > and a vector (which also has to be unique) so I assumed my type was
> > similar enough.
>
> The top of the hash_table library module does mention the fact
> that updates to hash tables should not be backtracked over, and why,
> and the fact that the compiler won't detect those errors.
>
> > This compiled fine but then the program fails with an exception because
> > (as far as I can see) when backtracking, the integer fields within the
> > `state` type do backtrack but the hash table doesn't.
>
> That is correct.
>
> > I am guessing that this is related to the first limitation mentioned in
> > the `LIMITATIONS` file and in the hash table module -- specifically,
> > that the Mercury compiler doesn't handle nested unique modes yet.
>
> That is also true.
>
> > My questions are:
> >
> > 1. Is my understanding above correct?
>
> Yes.
>
> > 2. Are there still plans to fix nested unique modes? Also, is this
> > something that is being worked on?
>
> Vague plans, but nothing concrete. Support for partially instantiated
> data structures and nested unique modes turned out to be way less important
> in practice than we originally thought, for most uses of Mercury. You are
> just unfortunate to fall outside this category of "most uses".
>
> > 3. Is there a way to still use hash tables or vectors within other types
> > somewhat safely, i.e. in a way that the compiler warns if the code
> > may backtrack unexpectedly, like it usually happens with the `io` type?
>
> At the moment, it is up to the user to avoid backtracking over updates
> that are (a) implemented destructively, but (b) described to the compiler
> using non-destructive modes, such as the mode aliasas in array.m and
> hash_table.m, and your error.m. Since the compiler does not know that
> these updates are in fact destructive, it cannot warn about those updates
> being backtracked over.
>
> If you lie to the compiler, no matter how necessary the lie, don't be
> surprised if the compiler believes you.
>
> > These are the issues in the first limitation that I am struggling with:
> >
> > 1. It says that "definite aliasing" is "not allowed", however I still
> > don't quite understand what "definite aliasing" is
>
> It is allowing two free variables to be unified, which means that they become
> aliases of each other. If e.g. X is unified with Y while both are free variables,
> then binding X to a term, such as f(a, b), will bind Y to f(a, b) as well,
> as a form of what Einstein called "spooky action at a distance". It is such
> "action at a distance" that the Mercury compiler cannot handle.
>
> I have just committed a change to LIMITATIONS that should explain that.
>
> > or what
> > "is not allowed" means (does the compiler give a warning or error in
> > this case or is the program simply miscompiled?).
>
> The program won't be miscompiled, nor will it give a warning. Whether
> you get an error or not depends on whether mode analysis finds a way
> to reorder whatever conjunction contains X = Y to delay that unification
> until at least one of X and Y is ground. If it finds such a reordering,
> then there is no aliasing needed, and the code will be compiled, and will work.
> If it does not find a reordering, it will give you an error message.
>
> > 2. It says that "partial instantiation" and "nested unique modes" are
> > "unusable", but again, it doesn't explain what "partial instantiation"
> > means
>
> A partially instantiated term is one that contains both function symbols
> and free variables. It is the middle of a spectrum, at one end of which
> are free variables, and the other end ground terms.
>
> > nor what "unusable" means in this case.
>
> It means that in most use cases, the compiler won't find the reordering
> described above, and will reject your program.
>
> > Again, does the compiler
> > give a warning or error or is the program simply miscompiled?
>
> Same answer as above.
>
> > 3. It then gives a detailed explanation, but I'm not sure if the detailed
> > explanation refers to the whole "definite aliasing" limitation or only to
> > the "partial instantiation working by chance" issue.
>
> I don't understand what you mean by that.
>
> > 4. The detailed explanation talks about scope, but again I don't know
> > what scope means in this case (what other scopes are there?)
>
> The rewording should explain that.
>
> > 5. It refers to Mantis bug 311, which seems to have nothing to do with
> > nested unique modes, I think.
>
> No, it does not, but it does involve partially instantiated terms.
>
> > 6. The first limitation would be much clearer if there were some
> > examples of code which works (including the special case mentioned in
> > the detailed explanation)
>
> That special case has no useful use case.
>
> > and code which should work but doesn't (and
> > whether it doesn't because the compiler fails or because the program
> > will misbehave at runtime).
>
> My just committed diff to LIMITATIONS has such an example.
>
> I would advise learning Mercury using purely functional data structures first,
> and only switching to destructively updated data structures once you have got
> the hand of the language. Starting with hash tables is like starting swimming
> lessons at the deep end instead of in the kiddie pool.
>
> Zoltan.
More information about the users
mailing list