[m-dev.] Feature proposal: generic inline iterations
Mark Brown
mark at cs.mu.OZ.AU
Thu Dec 22 23:44:38 AEDT 2005
On 22-Dec-2005, Sebastian Brand <sbrand at csse.unimelb.edu.au> wrote:
> Hi Mark,
>
>
> | It would be nice if the new feature worked well with state variable syntax.
> | For example, using the above form, it could be possible to write
> |
> | fromto(First1, !Local1, Last1)
> |
>
> Good point. This would be quite useful in case of nested
> iterations (the parent loop has local vars, the child loop
> as well). On the other hand, there is a value in sticking
> to established state of affairs. So I'd have a slight
> preference for the given ordering.
I'm not too fussed about it. In any case, we should sort out the semantics
before making any decisions about syntax -- I probably shouldn't have
brought it up at this stage.
> | It would be desirable to be able to specify the modes of the fromto/4
> | arguments and to specify the determinism of the goal, much as we do for
> | lambda expressions. In fact, it may be necessary to do this if mode/detism
> | inference proves too hard to implement.
> |
> | For example, the following specifies the modes:
> |
> | (
> | fromto(First1::in, In1::in, Out1::in, Last1::in),
> | fromto(First2::in, In2::in, Out2::out, Last2::out)
> | do
> | ...
> | )
>
> I'd hope very much that this could be avoided, and that
> looking at the context would suffice. Perhaps it can be
> optional, to be used when the compiler analysis fails.
Personally, I'd much rather be reading code that had explicit modes
on loops ;-). My number one problem with understanding these constructs
in Eclipse is figuring out the modes. YMMV.
More importantly, though, it seems that the (declarative) semantics depends
on the modes -- they determine which unifications go in the condition and
which go in the "then" branch. Admittedly it's not as bad as using cut,
but it is still a good argument for making the modes compulsory, or at
least making the modes obvious in some other way. Needing to look at the
context in order to determine the semantics would be a Bad Thing.
(Also, FWIW, it was reasoning about the modes and determinism that made me
realise there was this issue with the semantics in the first place. There
is probably a lesson in that somewhere, I think.)
One way to make the modes more obvious would be to have different iteration
specifiers that mean the same as "fromto" in Eclipse, but which have
different requirements on the modes of First and Last. For example, we
could use "fromto" to mean that First and Last both have mode "in" (and
therefore that this specifier sets the termination condition) and use
"acc" to mean that either First or Last has mode "out" (which is just a
general accumulator that doesn't cause any termination). This is similar
to how Eclipse has both "for" and "count".
A related issue is what to do when two iteration specifiers set a
termination condition, but they disagree. In Eclipse this is simple -- you
just fail (*) -- but in Mercury we will often want to write iterators that
require two lists to be the same length but which we want to be inferred det,
in which case we should throw an exception (cf. list.map_corresponding).
Perhaps there should be a specifier such as "det_fromto" which throws an
exception if it disagrees with any other specifier on termination?
>
>
> | > Parameter passing is done by a fromto(P, P, P, P). Etc.
> |
> | It would be nice to be able to use non-local vars in the body. These would
> | be processed as extra arguments to the do_XX predicate (similarly to how we
> | handle non-locals in lambda expressions).
>
> The more readible shortcuts, eg. foreach(X, List),
> for(I,A,B), param(P) = fromto(P, P, P, P), can be treated a
> bit more cleverly than by a direct reduction to their
> fromto form. For param(P), one doesn't need a separate Out
> argument; same goes for foreach, where Out = [].
Do we really need param/1 at all? Or to put it another way: what should be
the default quantification for variables which occur in the body but not in
the iteration specifiers? In Eclipse the default is that they are
existentially quantified in the body -- hence the need for param/1 -- but
the rationale for Eclipse doing this doesn't really apply to Mercury.
IMHO, we should treat non-locals the same way as they are treated in
lambda expressions. If someone wants a local variable in the body which
has the same name as a variable outside the do-goal, then they should use
an explicit quantifier.
Cheers,
Mark.
(*) At least, that's what I thought would happen. Consider the query:
(
for(I, 1, 3),
for(J, 1, 4)
do
writeln("I'm loopy!)
).
Not to criticise Eclipse too much, but I think we should do a lot better
in terms of the safety of termination conditions.
--------------------------------------------------------------------------
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