[m-rev.] for review: end-user documentation for Erlang backend

Julien Fischer juliensf at csse.unimelb.edu.au
Wed Jul 18 14:54:43 AEST 2007


On Wed, 18 Jul 2007, Peter Wang wrote:

> Estimated hours taken: 6
> Branches: main
>
> Add more documentation for the Erlang backend.
>
> Make it possible to configure and install the Erlang backend without too
> much manual tweaking.
>
> NEWS:
> 	Mention the Erlang backend.
>
> README.Erlang:
> 	Add installation and other notes for Erlang.
>
> doc/reference_manual.texi:
> doc/user_guide.texi:
> 	Add documentation for Erlang.
>
> aclocal.m4:
> configure.in:
> 	Check that the bootstrap compiler knows about the
> 	builtin_compound_{eq,lt} builtins, and understands
> 	--erlang-native-code.
>
> 	Make configure check for Erlang tools.
>
> 	Add configure --enable-erlang-grade option.  Erlang support
> 	is disabled by default.
>
> scripts/Mercury.config.in:
> 	Add `--erlang-compiler <erl>' and `--erlang-interpreter <erlc>'
> 	options to be set by configure.
>
> analysis/ANALYSIS_FLAGS.in:
> compiler/COMP_FLAGS.in:
> mdbcomp/MDBCOMP_FLAGS.in:
> 	Add `--erlang-include-directory <dir>/Mercury/hrls' options so that
> 	the compiler can find Erlang header files from other subdirectories.
>
> compiler/Mercury.options:
> library/Mercury.options:
> 	Work around bugs in the HiPE compiler when compiling two modules.
>
> 	Delete the workaround that was necessary while bootstrapping
> 	builtin_compound_{eq,lt}.
>
> compiler/options_file.m:
> 	Support ERLANG_FLAGS, EXTRA_ERLANG_FLAGS variables in options files to
> 	be the same as passing --erlang-flags.
>
> browser/Mmakefile:
> compiler/Mmakefile:
> deep_profiler/Mmakefile:
> library/Mmakefile:
> mdbcomp/Mmakefile:
> profiler/Mmakefile:
> runtime/Mmakefile:
> slice/Mmakefile:
> trace/Mmakefile:
> 	Make the build system do the same things in the Erlang grade as for
> 	the IL and Java grades.
>
> scripts/final_grade_options.sh-subr:
> scripts/parse_grade_options.sh-subr:
> 	Make these scripts know about the erlang grade so that parts of the
> 	build system won't abort on seeing it.

...

> Index: README.Erlang
> ===================================================================
> RCS file: README.Erlang
> diff -N README.Erlang
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ README.Erlang	18 Jul 2007 02:37:33 -0000
> @@ -0,0 +1,230 @@
> +-----------------------------------------------------------------------------
> +
> +INTRODUCTION
> +
> +This release of Mercury contains a port to Erlang.  The Mercury
> +compiler will generate Erlang source code that can be compiled into
> +bytecode or native code suitable for running in the Erlang runtime
> +system.
> +
> +The port is incomplete.  Large parts of the Mercury standard library
> +are not yet implemented.  Some RTTI related features are incompletely
> +or incorrectly implemented.
> +
> +PREREQUISITES
> +
> +In order to try this system you will need
> +
> +	- The Erlang/OTP distribution, which is open source and can be
> +	  downloaded from
> +		<http://www.erlang.org/download.html>
> +
> +	- The Mercury source distribution.  See below for installation
> +	  instructions.
> +
> +	  If you're reading this file from somewhere other than the
> +	  Mercury distribution, try the Mercury homepage at
> +	  	<http://www.mercury.csse.unimelb.edu.au>
> +
> +	- An installed Mercury compiler.  You must use `mmc --make' to
> +	  install the standard library for Erlang.  See below.
> +
> +	- A Unix-like environment.  The Erlang support has not been
> +	  tested on Windows, but you will need a shell script
> +	  interpreter.
> +
> +WARNING
> +
> +Please note that the Erlang backend is still an experimental feature.
> +
> +-----------------------------------------------------------------------------
> +
> +INSTALLATION
> +
> +The Mercury compiler itself can be installed with Erlang support as
> +usual, but the standard library can currently only be built for the
> +Erlang using `mmc --make'.  Therefore you must already have an
> +installed Mercury compiler available.
> +
> +Invoke configure with the option `--enable-erlang-grade' in order to
> +enable Erlang support.  Make sure it was detected properly by running:
> +
> +    mmake echo_libgrades
> +
> +Then run:
> +
> +    mmake --use-mmc-make install
> +or
> +    mmake --use-mmc-make install LIBGRADES=erlang
> +
> +For better performance you will need to add the following line to
> +Mmake.params before installing:
> +
> +    EXTRA_MCFLAGS += --erlang-native-code
> +-----------------------------------------------------------------------------
> +
> +THE ERLANG GRADE
> +
> +The Mercury compiler currently supports the grade `erlang'.
> +The erlang grade is enabled by using any of the options
> +`--grade erlang', `--target erlang', or just `--erlang',
> +in combination with `mmc --make'.  Mmake does _not_ currently support
> +the erlang grade.
> +
> +To run a Mercury program using the erlang grade, you need to build the
> +Mercury library in the erlang grade, using the Mercury source distribution.
> +
> +You can now build programs such as hello.m or calculator.m in the samples
> +directory.
> +
> +	cd samples
> +	mmc --make --erlang hello
> +
> +Now you can run hello
> +
> +	./hello
> +
> +Note that hello is a simple shell script that starts the Erlang
> +runtime system.  The actual object files will be stored in the Mercury
> +subdirectory, in `beams'.
> +
> +-----------------------------------------------------------------------------
> +
> +USING ERLANG
> +
> +The Mercury standard library has not been fully ported to Erlang yet.
> +The use of unimplemented procedures will result in a run-time error,
> +with a message such as "Sorry, not implemented: foreign code for this
> +function", and a stack trace.
> +
> +If you find missing functionality, you can interface to Erlang using
> +Mercury's foreign language interface.
> +
> +For more information about the foreign language interface, see the Mercury
> +Language Reference Manual, which you can find at:
> +
> +     <http://www.mercury.csse.unimelb.edu.au/information/documentation.html>
> +
> +-----------------------------------------------------------------------------
> +
> +PERFORMANCE NOTES
> +
> +The Erlang code generated by the Mercury compiler is designed to be compiled
> +to native code, using the HiPE compiler.  The Erlang bytecode compiler does
> +not recognise static data structures so some run-time type information can
> +get created repeatedly again at runtime.  HiPE treats static data structures
> +specially so does not have this problem.
>
 	... so this problem does not occur.

> +You can pass the `--erlang-native-code' option to mmc to use HiPE to compile
> +.erl files to .beam files.  It is recommended to add this flag to
> +Mmake.params before installing the standard library.
> +
> +The need to support user-defined equality and comparison predicates can
> +cause significant slowdowns, even when they are unused.  This problem
> +usually exists when a type contains an abstract type in its definition.  The
> +compiler does not know if an abstract type has user-defined equality or not,
> +so makes a conservative assumption.  Enabling intermodule optimisation gives

 	... so it makes a conservative ...

> +the compiler enough information to avoid this problem.

I wouldn't have thought so.

> +-----------------------------------------------------------------------------
> +
> +DIFFERENCES FROM OTHER BACKENDS
> +
> +* Discriminated union values are ordered according to Erlang conventions
> +  (e.g. alphabetically) instead of according to the order that data
> +  constructors appear in the type definition.
> +
> +* Some legal Mercury code making use of partial instantiation will be
> +  rejected when compiling to Erlang (you will get a compiler abort).
> +  An example is:
> +
> +    foo(Xs) :-
> +	( Xs = []
> +	; Xs = [1 | _]
> +	),
> +	( Xs = []
> +	; Xs = [_ | []]
> +	).
> +

...

> +FREQUENTLY ASKED QUESTIONS (FAQS)
> +
> +Q. What are the advantages of using the Erlang back-end?
> +
> +A. The goal is to take advantage of the Erlang implementation for writing
> +   scalable and reliable server programs, which can be distributed over
> +   multiple machines and, possibly, updated at run-time.
> +
> +
> +Q. What version of Erlang should I be using?
> +
> +A. We have tested with Erlang/OTP R11-R3 and up.
> +
> +
> +Q. What features are not yet implemented for the Erlang back-end?
> +
> +A. The following language features are not supported and will not be:
> +
> +	trailing
> +	solver types

I can't think of why solver types wouldn't work.  (Although in the absence of
trailing they won't be very useful.)

Also:
 	tabling

> +
> +   The following implementation features are not supported:
> +
> +	Mercury-level debugging
> +	Mercury-level profiling

And Mercury-level debugging.

> +
> +   The following standard library modules are completely unimplemented:
> +
> +	benchmarking
> +	bit_buffer
> +	bitmap
> +	construct
> +	deconstruct
> +	dir
> +	thread
> +	thread.semaphore
> +	time
> +	version_array
> +
> +   In addition, many modules are incompletely implemented or have placeholder
> +   implementations.
> +
> +Q. So how do I enable Erlang-level debugging?

Delete "So".

> +
> +A. With great difficulty.  One way is to copy or symlink all the .erl and
> +   .hrl files used by the program, including those of the standard library,
> +   into a single directory.  Then build the .beam files with debugging
> +   enabled, e.g.
> +
> +	erlc +debug_info *.erl
> +
> +   Start up the Erlang runtime system and the debugger:
> +
> +	% erl
> +	...
> +	1> debugger:start().
> +
> +   In the debugger, select Module > Interpret... and choose the modules to
> +   interpret (probably "All").  At the erl prompt, the program can be started
> +   like so:
> +
> +	% hello:mercury__main_wrapper().
> +
> +   To run it a second time you may need to call `main_2_p_0' instead.
> +
> +   For more information, see the documentation for erlc and the Erlang
> +   debugger.

...

> + at node Erlang data passing conventions
> + at subsection Erlang data passing conventions
> +
> +The Mercury types @code{int}, @code{float} and @code{char}
> +are mapped to Erlang integers, floats and integers respectively.
> +A Mercury @code{string} is represented as a list of integers in Erlang.
> +
> +Mercury variables whose type is a Mercury discriminated union type
> +will be passed as an Erlang tuple with the first element of the tuple
> +being an Erlang atom named after the Mercury data constructor.

I suggest adding an example of how a du type is represented in Erlang
here.

> +Mercury variables whose type is a Mercury equivalence type
> +will be passed as the representation of the right hand side of the
> +equivalence type.
> +
> +This mapping is subject to change and you should try to avoid writing
> +code that relies heavily upon a particular representation of Mercury
> +terms.
> +
> +Arguments of dummy types, e.g. @samp{io.state}, are represented by the
> +atom @samp{false} when necessary.  They are not passed to and from
> +calls to monomorphic procedures.
> +
> +Mercury arguments declared with input modes are passed by value to the
> +corresponding Erlang function.
> +
> +The result of an Erlang function depends on the determinism of the
> +Mercury procedure that it was derived from.  Procedures which succeed
> +exactly once and have a single output variable return the single value
> +directly.  Procedures which succeed exactly once and have zero or two
> +or more output variables return a tuple of those output variables in
> +order.
> +
> +Procedures which are semideterministic return, on success, a tuple of
> +the variables with output modes (including when the number of output
> +variables is one).  On failure they return the Erlang atom
> + at samp{fail}.
> +
> +Procedures which are nondeterministic take as a final argument a
> +success continuation.  This is an function which has an input variable
> +for each variable of the Mercury procedure with an output mode.  For
> +each solution, the success continuation with the values of those
> +output variables.  When there are no more solutions the Erlang
> +function returns with an undefined value.
> +
> @c -----------------------------------------------------------------------
>
> @node Using foreign types from Mercury
> @@ -6903,7 +6948,7 @@
> :- pragma foreign_decl("@var{Lang}", local, @var{DeclCode}).
> @end example
>
> -Note: currently only the C backends support this variant
> +Note: currently only the C and Erlang backends support this variant
> of the @samp{pragma foreign_decl} declaration.
>
> The declarations for Mercury predicates or functions exported to a
> @@ -6976,6 +7021,7 @@
> * Interfacing with C# 		:: How to write code to interface with C#
> * Interfacing with IL 		:: How to write code to interface with IL
> * Interfacing with Java 	:: How to write code to interface with Java
> +* Interfacing with Erlang 	:: How to write code to interface with Erlang
> @end menu
>
> All Mercury implementations should support interfacing with C.
> @@ -7004,6 +7050,9 @@
> @item @samp{Java}
> Use the string @code{"Java"} to set the foreign language to Java.
>
> + at item @samp{Erlang}
> +Use the string @code{"Erlang"} to set the foreign language to Erlang.
> +
> @end table
>
> @c -----------------------------------------------------------------------
> @@ -7704,6 +7753,146 @@
>
> @c ----------------------------------------------------------------------------
>
> + at node Interfacing with Erlang
> + at subsection Interfacing with Erlang
> +
> + at menu
> +* Using pragma foreign_type for Erlang :: Declaring Erlang types in Mercury
> +* Using pragma foreign_proc for Erlang :: Calling Erlang code from Mercury
> +* Using pragma foreign_export for Erlang :: Calling Mercury from Erlang code
> +* Using pragma foreign_decl for Erlang :: Including Erlang declarations in Mercury
> +* Using pragma foreign_code for Erlang :: Including Erlang code in Mercury
> + at end menu
> +
> +
> + at node Using pragma foreign_type for Erlang
> + at subsubsection Using pragma foreign_type for Erlang
> +
> +An Erlang @samp{pragma foreign_type} declaration has the form:
> +
> + at example
> +:- pragma foreign_type("Erlang", @var{MercuryTypeName}, "").
> + at end example
> +
> +The effect of this declaration is that Mercury values of type
> + at var{MercuryTypeName} will be passed to and from Erlang foreign_procs
> +as having some representation unknown to Mercury.
> +
> + at node Using pragma foreign_proc for Erlang
> + at subsubsection Using pragma foreign_proc for Erlang
> +
> +The input and output variables for a Erlang @samp{pragma foreign_proc}
> +will be the Erlang representations as described in
> + at ref{Erlang data passing conventions}.
> +
> +The Erlang code in a @code{pragma foreign_proc} declaration
> +for a procedure whose determinism indicates that it can fail
> +must assign either @samp{true} or @samp{false} to the variable
> + at samp{SUCCESS_INDICATOR}.  For example:
> +
> + at example
> +:- pred string.contains_char(string, character).
> +:- mode string.contains_char(in, in) is semidet.
> +
> +:- pragma foreign_proc("Erlang",
> +	string.contains_char(Str::in, Ch::in),
> +        [will_not_call_mercury, promise_pure],
> +        "SUCCESS_INDICATOR = (string:chr(Str, Ch) =/= 0)").
> + at end example
> +
> +Arguments whose mode is input will have their values set by the
> +Mercury implementation on entry to the Erlang code.
> +The Erlang code must set the values
> +of all output variables, even if the procedure fails
> +(i.e. sets the @samp{SUCCESS_INDICATOR} variable to @code{false}).
> +
> + at node Using pragma foreign_export for Erlang
> + at subsubsection Using pragma foreign_export for Erlang
> +
> +A @samp{pragma foreign_export} declaration for Erlang has the form:
> +
> + at example
> +:- pragma foreign_export("Erlang", @var{MercuryMode}, "@var{Erlang_Name}").
> + at end example
> +
> +For example,
> +
> + at example
> +:- pragma foreign_export("Erlang", foo(in, in, out), "foo").
> + at end example
> +
> + at c XXX currently foreign_exported procedures won't be visible outside
> + at c the defining module.

If that restriction is still current then I think it user's ought
to be aware of it.

> +The type signature of the Erlang interface to a Mercury procedure is
> +described in @ref{Erlang data passing conventions}.
> +
> +Calling polymorphically typed Mercury procedures from Erlang is a little bit
> +more difficult than calling ordinary (monomorphically typed) Mercury
> +procedures.  The simplest method is to just create monomorphic forwarding
> +procedures that call the polymorphic procedures, and export them, rather
> +than exporting the polymorphic procedures.
> +
> +If you do export a polymorphically typed Mercury procedure, the compiler
> +will prepend one @samp{type_info} argument to the parameter list of
> +the Erlang interface function for each polymorphic type variable in the
> +Mercury procedure's type signature.  The caller must arrange to pass
> +in appropriate @samp{type_info} values corresponding to the types
> +of the other arguments passed.  These @samp{type_info} arguments can
> +be obtained using the Mercury @samp{type_of} function in the Mercury
> +standard library module @samp{type_desc}.
> +
> + at node Using pragma foreign_decl for Erlang
> + at subsubsection Using pragma foreign_decl for Erlang
> +
> + at samp{pragma foreign_decl} declarations for Erlang can be used to provide
> +any top-level Erlang declarations (e.g.@: @samp{-define} macro declarations)
> +which are needed by Erlang code.
> +
> + at samp{pragma foreign_decl} blocks which do not have the @samp{local} attribute
> +will be copied into the @samp{.hrl} header file for that module, and
> +automatically included by other modules that import the module.  Therefore
> + at samp{-export} directives and Erlang module attributes should only appear in
> + at samp{local} blocks.
> +
> +For example:
> +
> + at example
> +:- pragma foreign_decl("Erlang", "
> +	-define(FOO, 42).
> +").
> +:- pred hello(io.state::di, io.state::uo) is det.
> +:- pragma foreign_proc("Erlang",
> +	hello(_IO0::di, _IO::uo),
> +	[will_not_call_mercury],
> +"
> +	io:format(""FOO = ~w~n"", [?FOO])
> +").
> + at end example
> +
> + at node Using pragma foreign_code for Erlang
> + at subsubsection Using pragma foreign_code for Erlang
> +
> + at samp{pragma foreign_code} can be used to define additional Erlang functions
> +which can then be referenced by @samp{pragma foreign_proc} declarations for
> +Erlang from that module.  By adding @samp{-export} directives inside
> + at samp{pragma foreign_decl} declarations, those functions can additionally be
> +called from outside the defining module.
> +
> +For example:
> +
> + at example
> +:- pragma foreign_code("Erlang", "
> +	foo() -> io:put_chars(""Foo."").
> +").
> +
> +:- impure pred say_foo is det.
> +:- pragma foreign_proc("Erlang", say_foo,
> +	[will_not_call_mercury], "foo()").
> + at end example
> +

...

> Index: doc/user_guide.texi
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
> retrieving revision 1.535
> diff -u -r1.535 user_guide.texi
> --- doc/user_guide.texi	14 Jul 2007 02:33:00 -0000	1.535
> +++ doc/user_guide.texi	18 Jul 2007 02:37:34 -0000
> @@ -689,6 +689,11 @@
> @vindex EXTRA_JAVACFLAGS
> Options to pass to the Java compiler (if you are using it).
>
> + at item ERLANG_FLAGS and EXTRA_ERLANG_FLAGS
> + at vindex ERLANG_FLAGS
> + at vindex EXTRA_ERLANG_FLAGS
> +Options to pass to the Erlang compiler (if you are using it).
> +
> @item ML
> @vindex ML
> The executable that invokes the linker.
> @@ -7443,7 +7448,7 @@
> generated code, and also output some profiling
> information (the static call graph) to the file
> @samp{@var{module}.prof}.  @xref{Profiling}.
> -This option is not supported for the IL and Java back-ends.
> +This option is not supported for the IL, Java and Erlang back-ends.
>
> @sp 1
> @item @code{--memory-profiling} (grades: any grade containing @samp{.memprof})
> @@ -7456,14 +7461,15 @@
> generated code, and also output some profiling
> information (the static call graph) to the file
> @samp{@var{module}.prof}.  @xref{Using mprof for memory profiling}.
> -This option is not supported for the IL and Java back-ends.
> +This option is not supported for the IL, Java and Erlang back-ends.
>
> @sp 1
> @item @code{--deep-profiling} (grades: any grade containing @samp{.profdeep})
> @findex --deep-profiling
> @cindex Deep profiling
> Enable deep profiling by inserting the appropriate hooks in the generated code.
> -This option is not supported for the high-level C, IL and Java back-ends.
> +This option is not supported for the high-level C, IL, Java and Erlang
> +back-ends.

It would be simpler to say:

 	This option is only supported by the low-level C back-end.

rather than listing everything that doesn't support it.
Likewise, some of the above should just say "This option is only
supported by the C back-ends,"


>
> @ignore
> 	The following are basically useless, hence undocumented.
> @@ -7535,8 +7541,8 @@
> @samp{mps} is another conservative collector based on Ravenbrook Limited's
> MPS (Memory Pool System) kit.
> @samp{automatic} means the target language provides it.
> -This is the case for the IL and Java back-ends, which always use
> -the underlying IL or Java implementation's garbage collector.
> +This is the case for the IL, Java and Erlang back-ends, which always use
> +the underlying implementation's garbage collector.
>
> @sp 1
> @item @code{--use-trail} (grades: any grade containing @samp{.tr})
> @@ -7548,7 +7554,7 @@
> Enable use of a trail.
> This is necessary for interfacing with constraint solvers,
> or for backtrackable destructive update.
> -This option is not yet supported for the IL or Java back-ends.
> +This option is not yet supported for the IL, Java or Erlang back-ends.
>
> @sp 1
> @item @code{--maybe-thread-safe @{yes, no@}}
> @@ -7568,6 +7574,7 @@
> floating point values don't need to be boxed.  Double
> precision floats are used by default.
> This option is not yet supported for the IL or Java back-ends.
> +This option will not be supported for the Erlang back-end.
>
> @c RBMM is undocumented since it is still experimental.
> @c @sp 1

,,,

> Index: scripts/Mercury.config.in
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/scripts/Mercury.config.in,v
> retrieving revision 1.17
> diff -u -r1.17 Mercury.config.in
> --- scripts/Mercury.config.in	15 Nov 2006 08:12:56 -0000	1.17
> +++ scripts/Mercury.config.in	18 Jul 2007 02:37:34 -0000
> @@ -27,6 +27,8 @@
> MERCURY_JAVA_COMPILER=@JAVAC@
> MERCURY_JAVA_INTERPRETER=@JAVA_INTERPRETER@
> MERCURY_CSHARP_COMPILER=@MS_CSC@
> +MERCURY_ERLANG_COMPILER=@ERLC@
> +MERCURY_ERLANG_INTERPRETER=@ERL@
> # $(MATH_LIB) needs to be defined because it may
> # be used by the substitution for SHARED_LIBS.
> MATH_LIB=$(MERCURY_MATH_LIB)
> @@ -52,6 +54,8 @@
> 		--java-compiler "$(MERCURY_JAVA_COMPILER)" \
> 		--java-interpreter "$(MERCURY_JAVA_INTERPRETER)" \
> 		--csharp-compiler "$(MERCURY_CSHARP_COMPILER)" \
> +		--erlang-compiler "$(MERCURY_ERLANG_COMPILER)" \
> +		--erlang-interpreter "$(MERCURY_ERLANG_INTERPRETER)" \
> 		--cflags-for-ansi "@CFLAGS_FOR_ANSI@" \
> 		--cflags-for-optimization "@CFLAGS_FOR_OPT@" \
> 		--cflags-for-warnings "@CFLAGS_FOR_WARNINGS@" \

Do you also need to update Mercury.config.bootstrap.in?

Julien.


--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list