[m-rev.] diff: Add 99 bottles of beer sample
paul at bone.id.au
Fri Nov 20 17:58:52 AEDT 2015
On Fri, Nov 20, 2015 at 05:48:36PM +1100, Julien Fischer wrote:
> Hi Paul,
> On Fri, 20 Nov 2015, Paul Bone wrote:
> >Add 99 bottles of beer sample
> > Add this sample.
> > I found the original version of this sample on 99-bottles-of-beer.net.
> > I've updated it, _tried_ to post a comment to 99-bottles-of-beer.net,
> > added it to rosetta code and thought, being a small example, that it
> > should also belong here.
> Oooh, can I play this game too? If your aim is to provide a more
> idiomatic version, I'd suggest:
> - not using explicit recursion where the standard library already
> provides a procedure (int.fold_down) that does the same thing.
> - use if-then-else rather that (C->T;E)
> - there's lots of string appending using ++ going on in your version, I'd
> call append_list instead.
> I've attached an alternative version.
Feel free to update it.
> % vim: ts=4 et ft=mercury
> :- module beer2.
> :- interface.
> :- import_module io.
> :- pred main(io::di, io::uo) is det.
> :- implementation.
> :- import_module int.
> :- import_module list.
> :- import_module string.
> main(!IO) :- int.fold_down(beer, 0, 99, !IO).
Yeah, I should have used fold_down
> :- pred beer(int::in, io::di, io::uo) is det.
> beer(N, !IO) :-
> ( if N = 0 then
> io.print_line("Go to the store and buy some more!", !IO)
> bottles(N, " on the wall,\n", !IO),
> bottles(N, ".\nTake one down, pass it around,\n", !IO),
It's easier to follow if you start a new source code line, probably with a
new call to write_string, for the new-line in the song.
> bottles(N - 1, " on the wall.\n\n", !IO)
> :- pred bottles(int::in, string::in, io::di, io::uo) is det.
> bottles(N, T, !IO) :-
> ( if N = 0 then
> io.format("No more bottles of beer%s", [s(T)], !IO)
> else if N = 1 then
> io.format("1 bottle of beer%s", [s(T)], !IO)
> io.format("%d bottles of beer%s", [i(N), s(T)], !IO)
Why pass the IO state through everything? I try to avoid this where
conveinent. I think append_list would have been better, it avoids the
repeated string appends and keeps the code declrative. Maybe Mercury should
optimise that as a special case rather than relying on programmers to
understand the costs of ++.
More information about the reviews