[mercury-users] Mercury programmer required ;-)

Warwick HARVEY warwick at cs.mu.OZ.AU
Fri Sep 25 11:05:26 AEST 1998


Fergus writes:
> However, the big table approach is a bit verbose and arguably a bit
> low-level.  The following version is less efficient, but a bit more
> concise and high-level.

Just a *little* less efficient.  36s rather than 0.8s.  :-)

> There's also a couple of style questions such as whether to include
> type declarations and whether to use `read'/`print' or `io__read_char'

`read' of course barfs because the input isn't a well-formatted term, so
I've kept read_char, but changed everything else.

Peter Schachte does have a point about the language looking difficult to
program in.  This version looks far less daunting, but has the drawback that
people will probably criticise it for its lack of efficiency (I mean,
*searching* the string for each character?  :-).  Of course, many of the
reasons it looks difficult are features that make it good for writing
*large* systems, not toy programs like this one.


% File: rot13_concise.m
% Main authors: Warwick Harvey <wharvey at cs.monash.edu.au>
%               Fergus Henderson <fjh at cs.mu.oz.au>

%
% rot13_concise:
%
% Program to read its input, apply the rot13 algorithm, and write it out
% again.
%
% This version is more concise (but less efficient) than its companion,
% rot13_verbose.
%
% Key features:
% - is independent of character set (e.g. ASCII, EBCDIC)
% - has proper error handling
%

:- module rot13_concise.

:- interface.
:- import_module io.

:- pred main(state, state).
:- mode main(di, uo) is det.

:- implementation.
:- import_module char, int, string.

% The length of `alphabet' should be a multiple of `cycle'.
alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".
cycle = 26.

rot_n(N, Char) = RotChar :-
	char_to_string(Char, CharString),
	( if sub_string_search(alphabet, CharString, Index) then
		NewIndex = (Index + N) mod cycle + cycle * (Index // cycle),
		index_det(alphabet, NewIndex, RotChar)
	else
		RotChar = Char
	).

rot13(Char) = rot_n(13, Char).

main -->
	read_char(Res),
	( { Res = ok(Char) },
		print(rot13(Char)),
		main
	; { Res = eof }
	; { Res = error(ErrorCode) },
		{ error_message(ErrorCode, ErrorMessage) },
		stderr_stream(StdErr),
		print(StdErr, "rot13: error reading input: "),
		print(StdErr, ErrorMessage),
		nl(StdErr)
	).




More information about the users mailing list