[m-users.] Field access functions usage

Zoltan Somogyi zoltan.somogyi at runbox.com
Fri Aug 16 12:56:57 AEST 2019



On Thu, 15 Aug 2019 23:04:46 +0200, Dirk Ziegemeyer <dirk at ziegemeyer.de> wrote:
> init_foo = X :-
>     X^field_1 = 5,
>     X^field_2 = "bar".

Without declarations for the field functions, the compiler sees this
as two unifications: X = foo(5, _), and X = foo(_, "bar"). This is effectively
a Herbrand constraint satisfaction problem , which the compiler can solve.

In the presence of declarations for the field functions, one part of the compiler
generates the definitions of those functions if the programmer does not provide
those definitions, but the rest of the compiler just treats those functions as if
they were any other function. This means that it does NOT try to use its knowledge
of what the code of those functions is, since the programmer may decide to
redefine them at any time. After all, the whole point of such getters is to allow
the representation of a data item to change (e.g. changing 2d locations from
cartesian to polar coordinates) *without requiring any changes* in the code
that works on such items of data.

Given this fact, you get the error because you are effectively telling the compiler:
"there are two constraints on X, I am not telling you what they are, solve them".
This is obviously an impossible task.

As an aside, I would note that while code such as

  ptr->field1 = ...;
  ptr->field2 = ...;

is idiomatic code in C (and most other imperative languages) for filling in
all the fields of a structure,

  X^field_1 = ...,
  X^field_2 = ...

is NOT idiomatic code in Mercury. In C, you have no choice; in Mercury,
you do, and the alternative code X = foo(..., ...) is more direct, not least
because it shows, both to people and to the compiler, that it is specifying
the values of *all* the fields.

Zoltan.


More information about the users mailing list