[m-dev.] for review: improvements for record syntax
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Dec 7 16:42:12 AEDT 2000
On 07-Dec-2000, schachte at cs.mu.OZ.AU <schachte at cs.mu.OZ.AU> wrote:
> So what I've been calling policy (1) would translate X ^ f(A, B) into
> f(X, A, B). Let's call this apply_front(f(A,B), X).
Hmm, I don't think that works, at least not if you intend apply_front
to be referentially transparent (i.e. to have a declarative semantics,
defined in terms of the meaning of its argument, rather than just
being syntactic sugar with only a transformational semantics that
depends on the syntactic form of its argument).
In particular, if you write the goal
F = f(A, B), Foo = apply_front(F, X)
then I don't think that can mean the same as
Foo = f(X, A, B)
If it did, what would the type of `F' be?
Suppose `f' is declared as e.g.
:- func f(string, int, float) = char.
Currently in Mercury the term `f(A, B)' is defined to mean `func(C) =
f(A, B, C)', and it has type `func(float) = char' (and requires that
`A' have type `string' and `B' have type `int').
But for `apply_front' to work in examples like `F = f(A, B), apply_front(F, X)'
the meaning and type of `f(A, B)' would have to be something different.
I don't see any way to make that work.
That's why I suggested giving `^' a referentially opaque semantics
as syntactic sugar whose expansion depends on the syntactic form
of its argument -- to which Simon responded "That's horrible".
However, note that `:=' is not referentially transparent either.
For example, `Y = X^f1, R = (Y^f2 := Z)' is not
the same as `R = ((X^f1)^f2 := Z)'!
I think it is OK for things like `^' and `:=' to be just syntactic
sugar which have only a transformational semantics rather than a
declarative semantics, so long as the transformation is simple.
With proposal (1), where `X ^ F(...)' becomes `F(X, ...)',
the transformation for `^' is indeed sufficiently simple, IMHO --
e.g. it's much simpler than the transformation for `:='.
> If we make the
> restriction that the principal functor of the second argument of the
> '^'/2 term must always be bound at compile time, then we can unfold the
> call to apply_front inline, and everything works fine.
>
> But Simon is arguing that ^ is useful in general as a concise version
> of apply which puts the argument first and operation last. So it
> would look a little like a unix pipeline, allowing you to read it
> left-to-right, rather than inside-out (which amounts to right-to-left).
> So maybe we shouldn't have the known function name restriction.
>
> We could still get the same benefit, though, by translating ^ into
> apply_front/2. The problems with this are that Mercury doesn't have an
> apply_front/2 builtin (as I've argued before, it would have some
> efficiency advantages over apply, so maybe it would be worth adding);
As explained above, I don't think we can add an apply_front/2 builtin.
Also, I don't remember the supposed efficiency advantages, and I
suspect that they don't really exist and/or would not apply to the
MLDS back-end.
> I guess on balance, I'd still argue for policy (1) with the known
> function name restriction, and add the apply_front builtin (preferably
> for all arities >= 1) later so the restriction can be dropped.
I still prefer proposal (1) [with or without the function name
restriction] to proposal (2), because of the argument ordering, even
though `^' is not referentially transparent, and does not correspond
quite so directly to `apply'.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list