[m-dev.] a conditional field update operator

Paul Bone paul at bone.id.au
Wed Mar 8 16:55:20 AEDT 2017


On Wed, Mar 08, 2017 at 04:38:52PM +1100, Zoltan Somogyi wrote:
> 
> 
> On Wed, 8 Mar 2017 16:02:11 +1100, Paul Bone <paul at bone.id.au> wrote:
> > > Do people think such an extension to field syntax would be useful
> > > more generally than just in the Mercury compiler? If so, what should
> > > the syntax be?
> > 
> > Depending on the code that creates the new value (X), it might be more
> > appropriate to use a normal equality test.  It probably makes sense to
> > support both equality tests.
> 
> pointer_equal is a builtin that compares its operands as bit vectors;
> basically, it checks if the update would yield a new structure that is
> bit-identical to the old one. I don't see any situation in which it is *not*
> a correct test to use. (For integer and boolean fields, we often use
> New = Old as the test, but only because it is easier to type and to read;
> it is semantically identical to the pointer_equal test.)

Yes, it is the most conservative test.

However an equality test will catch items that are semantically equal, even
if not structurally or pointer equal, and avoid the memory allocation in
those situations also.  This may be what people want, but possibly less
often, although it might not be correct in some cases.


> > Since this would be very rarely used I'd hesitate to give it a
> > symbol/operator. 
> 
> The reasons why I am proposing a new operator is precisely because
> 
> - this is the nth time we have found a need for it in the compiler,
>   for largish values of n, and
> 
> - I think it is likely that in many cases, it is only the size and (at the moment)
>   relatively hard-to-read nature of the five-line version that prevents it
>   from being used instead of the one-line, always-allocate-a-new-structure
>   version. For example, the compiler has many passes that transform
>   parts of the HLDS *slightly*, leaving many or most parts of it intact.
>   If we had the new operator, we could use it to significantly reduce
>   the amount of memory being allocated by such passes.

Mmm, true.  I hadn't considered the cases where I _don't_ use such a
pattern, even though I could/should.

> Is your argument that you think such "rebuild with some rare modifications"
> operations are rare in general? Mike's previous mail seems to imply that
> he thinks just the opposite.

I had _assumed_ that they were rare. But your above example of the HLDS
reminded me of all the times I had done the same, and wished for something
like this.  I now think that making it a symbolic operator such as :?= is
best.

I assumed that Mike based his message off the idea that, at least in
Mercury's C grades, a memory allocation is quite expensive while a branch is
much cheaper.  Even if these are rare I guessed that he was thinking it
might be worth-while anyway.  If they are rare, I think it wouldn't be
worth-while.  And the cost to other transformations, such as coalescing
multiple structure updates together, would be at best annoying.

However, if we go to the effort of adding an operator such as :?=, it would
be interesting to see what happens if made it the default.

> > I'd prefer to give it a name, it may make it more awkward
> > to use but it's an operator that can be defined for something else later (if
> > necessary).
> > 
> >     update_field_if_not_pointer_equal(!Info ^ simp_varset, X),
> 
> I don't think "not adding another operator" is a worthwhile goal,
> and I don't see what else your proposal would accomplish.
>
> If you make conditional-update use a procedure call as its syntax,
> then either
> 
> - its implementation is also a procedure call, in which case
>   it is unnecessarily slow; or
> 
> - its implementation is not a procedure call but inline code,
>   it which case the compiler would have to have completely new code
>   to make the transformation.

I no-longer think this is a good idea.  But wouldn't it be recognised
directly by the parser, like a reserved word?

> Using the same overall syntax as !Info ^ field := X but with another
> operators is easier for us as implementors. And for users, the easiest
> way to make conditional-update easy to use, and to make switching
> from always-update to conditional-update, or vice versa, is to make
> condition-update a one-character change from the existing := operator.

These are good goals.


-- 
Paul Bone
http://paul.bone.id.au


More information about the developers mailing list