[m-dev.] Adding Loops to Mercury
Matt Giuca
matt.giuca at gmail.com
Sat Jan 4 23:48:33 AEDT 2014
Thanks for deeply considering my suggestion, Paul.
There is another reason I'd like to add in to the discussion, I apologise
> if someone has said this already. We have many predicates such as foldl,
> foldl2, foldl3 etc in the list module of the standard library. We also have
> map_corresponding and numerous other predicates, each predicate has a
> number of different modes. It can be painful when you need to use a
> predicate that fits one of these patterns in some ways, but doesn't fit the
> number of accumulators, number of output or input lists (map_corresponding)
> etc. This is particularly bad when the ADT is abstract (like maps, but
> unlike list) where you cannot write such a predicate without modifying the
> standard library.
>
Yep, this is what Peter Schachte was getting at, I think.
I think that the solution should be something smiliar to Matt's proposal
> (below) that can also work on integers. Peter Schachte's paper may also be
> useful but I've not read it, John's reference to Visual Prolog might also
> be
> useful. Additionally, one case where I've seen this done before was SISAL,
> a pure single assignment language that used loops that looked similar to
> imperative loops http://en.wikipedia.org/wiki/SISAL. Ultimately SISAL was
> not adopted by the programming community because Fortran programmers found
> it difficult to adjust to declrative programming. More about SISAL:
> http://www2.cmp.uea.ac.uk/~jrwg/Sisal/00.Contents.html Matt: is there
> something like this in Mars that we should also read?
>
Mars loops are just simple while loops with the same semantics as Python.
Nothing really special. (It isn't really relevant to Mercury because Mars
local variables are re-assignable; in this sense Mars semantics are much
closer to a conventional imperative language.)
>
> On Fri, Jan 03, 2014 at 11:14:29AM +1100, Matt Giuca wrote:
> > I would propose a for loop syntax for Mercury which can be used something
> > like this:
> >
> > :- pred print_key_values(assoc_list(string, string)::in, io::di, io::uo)
> is
> > det.
> > print_key_values(List, !IO) :-
> > for X-Y in List [!IO] (
> > io.write_string(X, !IO),
> > io.write_string(" = ", !IO),
> > io.write_string(Y, !IO),
> > io.nl(!IO)
> > ).
> >
> > The features of this syntax are:
> >
> > 1. Clearly shows that X-Y is the elements of List, and that List is
> the
> > list being iterated over.
> > 2. Only need to specify the accumulators once (!IO), instead of
> > specifying them both in the predicate head and as separate arguments.
> > 3. Works naturally with the !S state variable notation, not requiring
> > the user to break the illusion of S being a single variable and
> specify !.S
> > and !:S.
> > 4. Does not allow the "invention" of new accumulator names; instead,
> you
> > are merely specifying existing variables from the outer scope
> (typically
> > state variables) that may be updated in the body of the loop.
> > 5. Does not require the user to have to decide whether to use foldl,
> > foldl2, foldl3, etc. It works for any number of accumulator variables.
> > 6. It keeps the idea that the user must explicitly specify which
> > variables can be updated by the loop body. You can't just go updating
> any
> > state variable in the outer scope, for example.
> >
>
> This seems good to me, I would like to extend it though so that:
>
> 7. It can handle any number of input lists. (like map_corresponding).
> 8. It can handle things other than lists (I have some ideas about how
> to
> do this that I can describe later).
> 9. It can handle multiple outputs (not just accumoators) like list.map
> does.
> 10. Guards can be added to support filtering.
>
I would support all of these, as long as they can be added cleanly to the
syntax (i.e., all of these features are optional and I don't need to
provide, for example, a "returning" clause when I'm not using it for a map).
SISAL was a pure language that had structures like this that were used for
> looping and such more often than recursion. This and your own work show
> that the imperative/declarative dichotomy really is a false one (yes, I
> deliberately paraphrased one of your titles).
>
Thanks :)
Also, because you, and I'm sure others, would have found such a feature
> useful in Mercury means that it is valuable. If there are good ideas whose
> effort to implement and maintain are worthwhile then there's no reason we
> should reject them.
>
Julian's previous post suggests that something very similar to my
suggestion was attempted thirteen years ago, and was abandoned largely for
implementation reasons. If such a feature *is* going to add significant
implementation overhead, then that is a reason to think twice about it. Not
to say it should be abandoned again, but that the payoff has to be worth
the effort. As I'm not a Mercury developer, I can't speak to the difficulty
of implementing it, so I'll leave it to better minds to discuss.
Matt
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/developers/attachments/20140104/0994860b/attachment.html>
More information about the developers
mailing list