[m-dev.] for review: improvements for record syntax
schachte at cs.mu.OZ.AU
schachte at cs.mu.OZ.AU
Fri Dec 8 01:40:14 AEDT 2000
On 7 Dec, Fergus Henderson wrote:
> 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?
Oh, it's referentially transparent, you just can't type it. You'd have
no problem implementing it soundly in Prolog (if Prolog supported
functions, that is). But your point is well taken: it won't work in
Mercury. Bummer.
> 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.
It could be. You'd have to view ^ and := together as a single distfix
operator, though. If X ^ Y was implemented as Y(X) and X ^ Y := Z
as Y(X, Z), then you could define
:- func elem(K, map(K,T)) = T.
:- func elem(K, map(K,T), T) = map(K,T).
and you'd be able to write Field=elem(3), print(Map^Field). You could also
write Field=elem(3), print(Map^Field:=42). (The current Mercury type
checker might not be able to handle this, but it is typeable.) But,
sadly, you couldn't write Field=elem(3), print(Map^Field), print(Map^Field:=42)
due to the typing problem. What a pity; it would be really useful to be
able to pass around a (pseudo-)member name, and use it to access and
update a term's member.
> 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.
The efficiency advantage is that apply_front/N could be implement by
code that just loads arguments 2 through N of the apply_front/N goal
into argument registers 1 through N-1, and then enters a while loop that
copies the closure arguments into argument registers beginning with N,
and finally jumps to the closure's code. With apply_front, you know at
compile time what registers each argument is going to go in; not so with
apply.
You're probably right that you couldn't take advantage of that using
the MLDS back-end. Maybe somehow using varargs technology?
> 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'.
I don't see how you could ever implement policy (1) without the function
name restriction. That's why I'm flip-flopping to support policy (2)
now. I think there is more to be gained by allowing first-class values
on the right of ^ (even if not immediately) than is lost by a somewhat
confusing argument order on accessor and setter functions.
--
Peter Schachte The use of COBOL cripples the mind; its
mailto:schachte at cs.mu.OZ.AU teaching should, therefore, be regarded
http://www.cs.mu.oz.au/~schachte/ as a criminal offense.
PGP: finger schachte at 128.250.37.3 -- E. W. Dijkstra
--------------------------------------------------------------------------
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