[m-rev.] for review: add io.{write,print}_line

Julien Fischer jfischer at opturion.com
Wed Feb 12 17:10:15 AEDT 2014


For review by anyone.

Add io.{write,print}_line to the standard library.

Add the predicates io.write_line and io.print_line to the standard library.
These are versions of io.write and io.print respectively, that in addition to
printing their argument also print a final newline.  While this is no different
to calling io.{write,print} and then calling io.nl, it is a little more concise
which can be convenient in some circumstances.

library/io.m:
 	Add the above predicates.

compiler/error_util.m:
 	Avoid ambiguity with the write_line/3 predicate defined
 	in this module.

NEWS:
 	Announce the new predicates.

tests/hard_coded/write.m:
 	Use up-to-date syntax in this module.

 	Call write_line in a few spots.

Julien.

diff --git a/NEWS b/NEWS
index a08d669..f35b152 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,13 @@
+NEWS since Mercury 14.01
+------------------------
+
+Changes to the Mercury standard library:
+
+* We have added the print_line and write_line family of predicates to the
+  io module.  These behave like the print and write predicates, but also
+  write a terminating newline character.
+
+
  NEWS for Mercury 14.01
  ----------------------

diff --git a/compiler/error_util.m b/compiler/error_util.m
index 5c24267..d5f7298 100644
--- a/compiler/error_util.m
+++ b/compiler/error_util.m
@@ -990,7 +990,7 @@ write_lines([Line | Lines], MaybeContext, FixedIndent, !IO) :-
      Indent = FixedIndent + LineIndent * indent_increment,
      string.pad_left("", ' ', Indent, IndentStr),
      io.write_string(IndentStr, !IO),
-    write_line(LineWords, !IO),
+    error_util.write_line(LineWords, !IO),
      write_lines(Lines, MaybeContext, FixedIndent, !IO).

  :- pred write_line(list(string)::in, io::di, io::uo) is det.
diff --git a/library/io.m b/library/io.m
index 8b39037..135afae 100644
--- a/library/io.m
+++ b/library/io.m
@@ -376,7 +376,7 @@

  %-----------------------------------------------------------------------------%
  %
-% Text output predicates
+% Text output predicates.
  %

  % These will all throw an io.error exception if an I/O error occurs.
@@ -420,6 +420,20 @@

  :- pred io.print_cc(T::in, io::di, io::uo) is cc_multi.

+    % io.print_line calls io.print and then writes a newline character.
+    %
+:- pred io.print_line(T::in, io::di, io::uo) is det.
+
+:- pred io.print_line(io.output_stream::in, T::in, io::di, io::uo) is det.
+
+:- pred io.print_line(io.output_stream, deconstruct.noncanon_handling, T, io, io).
+:- mode io.print_line(in, in(do_not_allow), in, di, uo) is det.
+:- mode io.print_line(in, in(canonicalize), in, di, uo) is det.
+:- mode io.print_line(in, in(include_details_cc), in, di, uo) is cc_multi.
+:- mode io.print_line(in, in, in, di, uo) is cc_multi.
+
+:- pred io.print_line_cc(T::in, io::di, io::uo) is cc_multi.
+
      % io.write/3 writes its argument to the current output stream.
      % io.write/4 writes its second argument to the output stream specified
      % in its first argument. In all cases, the argument to output may be
@@ -454,6 +468,20 @@

  :- pred io.write_cc(T::in, io::di, io::uo) is cc_multi.

+    % io.write_line calls io.write and then writes a newline character.
+    %
+:- pred io.write_line(T::in, io::di, io::uo) is det.
+
+:- pred io.write_line(io.output_stream::in, T::in, io::di, io::uo) is det.
+
+:- pred io.write_line(io.output_stream, deconstruct.noncanon_handling, T, io, io).
+:- mode io.write_line(in, in(do_not_allow), in, di, uo) is det.
+:- mode io.write_line(in, in(canonicalize), in, di, uo) is det.
+:- mode io.write_line(in, in(include_details_cc), in, di, uo) is cc_multi.
+:- mode io.write_line(in, in, in, di, uo) is cc_multi.
+
+:- pred io.write_line_cc(T::in, io::di, io::uo) is cc_multi.
+
      % Writes a newline character to the current output stream.
      %
  :- pred io.nl(io::di, io::uo) is det.
@@ -4683,6 +4711,22 @@ io.print_cc(Term, !IO) :-
  io.print_to_stream(Stream, Term, !IO) :-
      io.print(output_stream(Stream), canonicalize, Term, !IO).

+io.print_line(Term, !IO) :-
+    io.print(Term, !IO),
+    io.nl(!IO).
+
+io.print_line(Stream, Term, !IO) :-
+    io.print(Stream, Term, !IO),
+    io.nl(!IO).
+
+io.print_line(Stream, NonCanon, Term, !IO) :-
+    io.print(Stream, NonCanon, Term, !IO),
+    io.nl(!IO).
+
+io.print_line_cc(Term, !IO) :-
+    io.print_cc(Term, !IO),
+    io.nl(!IO).
+
  %-----------------------------------------------------------------------------%
  %
  % Various different versions of io.write
@@ -4702,6 +4746,22 @@ io.write_cc(X, !IO) :-
      io.output_stream(Stream, !IO),
      stream.string_writer.write(Stream, include_details_cc, X, !IO).

+io.write_line(X, !IO) :-
+    io.write(X, !IO),
+    io.nl(!IO).
+
+io.write_line(Stream, X, !IO) :-
+    io.write(Stream, X, !IO),
+    io.nl(!IO).
+
+io.write_line(Stream, NonCanon, X, !IO) :-
+    io.write(Stream, NonCanon, X, !IO),
+    io.nl(!IO).
+
+io.write_line_cc(X, !IO) :-
+    io.write_cc(X, !IO),
+    io.nl(!IO).
+
  %-----------------------------------------------------------------------------%

  io.write_list([], _Separator, _OutputPred, !IO).
diff --git a/tests/hard_coded/write.m b/tests/hard_coded/write.m
index faf13a4..564e374 100644
--- a/tests/hard_coded/write.m
+++ b/tests/hard_coded/write.m
@@ -1,4 +1,5 @@
-% Test case for io__write
+% vim: ft=mercury ts=4 sw=4 et
+% Test case for io.write (and io.write_line).
  %
  % Author: trd

@@ -6,161 +7,169 @@
  :- interface.
  :- import_module io.

-:- pred main(io__state::di, io__state::uo) is det.
+:- pred main(io::di, io::uo) is det.

  :- implementation.

  :- import_module list, int, term, map, array, univ.
  :- import_module version_array.

-:- pred test_ops(io__state::di, io__state::uo) is det.
-:- pred test_builtins(io__state::di, io__state::uo) is det.
-:- pred test_discriminated(io__state::di, io__state::uo) is det.
-:- pred test_polymorphism(io__state::di, io__state::uo) is det.
-:- pred test_other(io__state::di, io__state::uo) is det.
-:- pred newline(io__state::di, io__state::uo) is det.
-
-
-:- type enum	--->	one	;	two	;	three.
-
-:- type fruit	--->	apple(list(int))
-		;	banana(list(enum)).
-
-:- type thingie	--->	foo ; bar(int) ; bar(int, int) ; qux(int) ;
-			quux(int) ; quuux(int, int) ; wombat ; 
-			zoom(int) ; zap(int, float) ; zip(int, int) ;
-			zop(float, float).
-
-:- type poly(A, B)	--->	poly_one(A) ; poly_two(B) ; 
-				poly_three(B, A, poly(B, A)).
-
-:- type no_tag		---> 	qwerty(int).
-
-:- type expr		--->	var(string)
-			;	int(int)
-			;	expr + expr
-			;	expr - expr
-			; 	expr * expr
-			;	(expr, expr)
-			;	{expr; expr}
-			;	{{expr}}
-			;	(type)
-			;	blah
-			;	(:-)
-			.
-
-main -->
-	test_ops,
-	test_discriminated,
-	test_polymorphism,
-	test_builtins, 
-	test_other.
-
-
-test_ops -->
-	io__write(var("X") + int(3) * var("X^2") ; (type)), newline,
-	io__write(write.{type}), newline,
-	io__write(write.{:-}), newline,
-	io__write((:-)), newline,
-	io__write(write.{blah}), newline,
-	io__write((blah ; (type), (type) * blah ; (type))), newline,
-	io__write(((blah ; blah), blah) * blah ; blah), newline,
-	io__write((type) * blah ; (type)), newline.
-
-test_discriminated -->
-	io__write_string("TESTING DISCRIMINATED UNIONS\n"),
-
-		% test enumerations
-	io__write(one), newline,
-	io__write(two), newline,
-	io__write(three), newline,
-
-		% test simple tags
-	io__write(apple([9,5,1])), newline,
-	io__write(banana([three, one, two])), newline,
-
-		% test complicated tags
-	io__write(zop(3.3, 2.03)), newline,
-	io__write(zip(3, 2)), newline,
-	io__write(zap(3, -2.111)), newline,
-
-		% test complicated constant
-	io__write(wombat), newline,
-	io__write(foo), newline,
- 
-	newline. 
-
-test_polymorphism -->
-	io__write_string("TESTING POLYMORPHISM\n"),
-	io__write(poly_one([2399.3])), newline,
-	io__write(poly_two(3)), newline,
-	io__write(poly_three(3.33, 4, poly_one(9.11))), newline,
-
-	newline.
-
-
-test_builtins -->
-	io__write_string("TESTING BUILTINS\n"),
-
-		% test strings
- 	io__write(""), newline,
- 	io__write("Hello, world\n"), newline,
- 	io__write("Foo%sFoo"), newline,
- 	io__write(""""), newline,	% interesting - prints """ of course
-
-		% test characters
-	io__write('a'), newline,
-	io__write('&'), newline,
-
-		% test floats
-	io__write(3.14159), newline,
-	io__write(11.28324983E-22), newline,
-	io__write(22.3954899E22), newline,
-
-		% test integers
-	io__write(-65), newline,
-	io__write(4), newline,
-
-		% test univ.
-	{ type_to_univ(["hi! I'm a univ!"], Univ) }, 
-	io__write(Univ), newline,
- 
-		% test predicates 
-	io__write(newline), newline,
-
-	newline.
-
-
-
-	% Note: testing abstract types is always going to have results
-	% that are dependent on the implementation. If someone changes
-	% the implementation, the results of this test can change.
-
-test_other -->
-	io__write_string("TESTING OTHER TYPES\n"),
-	{ term__init_var_supply(VarSupply) },
-	{ term__create_var(Var, VarSupply, NewVarSupply) },
-	io__write(Var), newline,
-	io__write(VarSupply), newline,
-	io__write(NewVarSupply), newline,
-
-		% presently, at least, map is an equivalence and
-		% an abstract type.
-	{ map__init(Map) },
-	io__write(Map), newline,
-
-		% a no tag type 
-	io__write(qwerty(4)), newline,
-
-	{ array__from_list([1,2,3,4], Array) },
-	io__write(Array), newline,
-
-	{ VersionArray = version_array.from_list([1,2,3,4]) },
-	io.write(VersionArray), newline,
-
-	newline.
-
-newline -->
-	io__write_char('\n').
-
-
+:- pred test_ops(io::di, io::uo) is det.
+:- pred test_builtins(io::di, io::uo) is det.
+:- pred test_discriminated(io::di, io::uo) is det.
+:- pred test_polymorphism(io::di, io::uo) is det.
+:- pred test_other(io::di, io::uo) is det.
+:- pred newline(io::di, io::uo) is det.
+
+:- type enum
+    --->    one
+    ;       two
+    ;       three.
+
+:- type fruit
+    --->    apple(list(int))
+    ;       banana(list(enum)).
+
+:- type thingie
+    --->    foo
+    ;       bar(int) 
+    ;       bar(int, int)
+    ;       qux(int) 
+    ;       quux(int)
+    ;       quuux(int, int) 
+    ;       wombat 
+    ;       zoom(int) 
+    ;       zap(int, float) 
+    ;       zip(int, int)
+    ;       zop(float, float).
+
+:- type poly(A, B)
+    --->    poly_one(A)
+    ;       poly_two(B)
+    ;       poly_three(B, A, poly(B, A)).
+
+:- type no_tag
+    --->    qwerty(int).
+
+:- type expr
+    --->    var(string)
+    ;       int(int)
+    ;       expr + expr
+    ;       expr - expr
+    ;       expr * expr
+    ;       (expr, expr)
+    ;       {expr; expr}
+    ;       {{expr}}
+    ;       (type)
+    ;       blah
+    ;       (:-).
+
+main(!IO) :-
+    test_ops(!IO),
+    test_discriminated(!IO),
+    test_polymorphism(!IO),
+    test_builtins(!IO), 
+    test_other(!IO).
+
+test_ops(!IO) :-
+    io.write(var("X") + int(3) * var("X^2") ; (type), !IO), newline(!IO),
+    io.write(write.{type}, !IO), newline(!IO),
+    io.write(write.{:-}, !IO), newline(!IO),
+    io.write((:-), !IO), newline(!IO),
+    io.write(write.{blah}, !IO), newline(!IO),
+    io.write((blah ; (type), (type) * blah ; (type)), !IO), newline(!IO),
+    io.write(((blah ; blah), blah) * blah ; blah, !IO), newline(!IO),
+    io.write((type) * blah ; (type), !IO), newline(!IO).
+
+test_discriminated(!IO) :-
+    io.write_string("TESTING DISCRIMINATED UNIONS\n", !IO),
+
+    % Test enumerations.
+    io.write_line(one, !IO),
+    io.write_line(two, !IO),
+    io.write_line(three, !IO),
+
+    % Test simple tags.
+    io.write(apple([9,5,1]), !IO), newline(!IO),
+    io.write(banana([three, one, two]), !IO), newline(!IO),
+
+    % Test complicated tags.
+    io.write(zop(3.3, 2.03), !IO), newline(!IO),
+    io.write(zip(3, 2), !IO), newline(!IO),
+    io.write(zap(3, -2.111), !IO), newline(!IO),
+
+    % Test complicated constant.
+    io.write(wombat, !IO), newline(!IO),
+    io.write(foo, !IO), newline(!IO),
+ 
+    newline(!IO). 
+
+test_polymorphism(!IO) :-
+    io.write_string("TESTING POLYMORPHISM\n", !IO),
+    io.write(poly_one([2399.3]), !IO), newline(!IO),
+    io.write(poly_two(3), !IO), newline(!IO),
+    io.write(poly_three(3.33, 4, poly_one(9.11)), !IO), newline(!IO),
+
+    newline(!IO).
+
+test_builtins(!IO) :-
+    io.write_string("TESTING BUILTINS\n", !IO),
+
+    % Test strings.
+    io.write("", !IO), newline(!IO),
+    io.write("Hello, world\n", !IO), newline(!IO),
+    io.write("Foo%sFoo", !IO), newline(!IO),
+    io.write("""", !IO), newline(!IO),    % interesting - prints """ of course
+
+    % Test characters.
+    io.write('a', !IO), newline(!IO),
+    io.write('&', !IO), newline(!IO),
+
+    % Test floats.
+    io.write(3.14159, !IO), newline(!IO),
+    io.write(11.28324983E-22, !IO), newline(!IO),
+    io.write(22.3954899E22, !IO), newline(!IO),
+
+    % Test integers.
+    io.write(-65, !IO), newline(!IO),
+    io.write(4, !IO), newline(!IO),
+
+    % Test univ.
+    type_to_univ(["hi! I'm a univ!"], Univ), 
+    io.write(Univ, !IO), newline(!IO),
+ 
+    % Test predicates.
+    io.write(newline, !IO), newline(!IO),
+
+    newline(!IO).
+
+    % Note: testing abstract types is always going to have results
+    % that are dependent on the implementation. If someone changes
+    % the implementation, the results of this test can change.
+    %
+test_other(!IO) :-
+    io.write_string("TESTING OTHER TYPES\n", !IO),
+    term.init_var_supply(VarSupply),
+    term.create_var(Var, VarSupply, NewVarSupply),
+    io.write(Var, !IO), newline(!IO),
+    io.write(VarSupply, !IO), newline(!IO),
+    io.write(NewVarSupply, !IO), newline(!IO),
+
+    % Presently, at least, map is an equivalence and
+    % an abstract type.
+    map.init(Map),
+    io.write(Map, !IO), newline(!IO),
+
+    % A no tag type.
+    io.write(qwerty(4), !IO), newline(!IO),
+
+    array.from_list([1,2,3,4], Array),
+    io.write(Array, !IO), newline(!IO),
+
+    VersionArray = version_array.from_list([1,2,3,4]),
+    io.write(VersionArray, !IO), newline(!IO),
+
+    newline(!IO).
+
+newline(!IO) :-
+    io.write_char('\n', !IO).



More information about the reviews mailing list