..
   This file is part of Logtalk <https://logtalk.org/>  
   Copyright 1998-2018 Paulo Moura <pmoura@logtalk.org>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


.. _programming_programming:

Writing, running, and debugging applications
============================================

.. _programming_writing:

Writing applications
--------------------

For a successful programming in Logtalk, you need a good working
knowledge of Prolog and an understanding of the principles of
object-oriented programming. Most guidelines for writing good Prolog
code apply as well to Logtalk programming. To those guidelines, you
should add the basics of good object-oriented design.

One of the advantages of a system like Logtalk is that it enable us to
use the currently available object-oriented methodologies, tools, and
metrics [Champaux92]_ in logic programming. That said, writing applications
in Logtalk is similar to writing applications in Prolog: we define new
predicates describing what is true about our domain objects, about our
problem solution. We encapsulate our predicate directives and definitions
inside new objects, categories, and protocols that we create by hand with
a text editor or by using the Logtalk built-in predicates. Some of the
information collected during the analysis and design phases can be
integrated in the objects, categories and protocols that we define by
using the available entity and predicate documenting directives.

.. _programming_source_files:

Source files
~~~~~~~~~~~~

Logtalk source files may define any number of entities (objects,
categories, or protocols) and Prolog code. If you prefer to define each
entity in its own source file, then it is recommended that the source
file be named after the entity identifier. For parametric objects, the
identifier arity can be appended to the identifier functor. By default,
all Logtalk source files use the extension ``.lgt`` but this is optional
and can be set in the adapter files. Intermediate Prolog source files
(generated by the Logtalk compiler) have, by default, a ``_lgt`` suffix
and a ``.pl`` extension. Again, this can be set to match the needs of a
particular Prolog compiler in the corresponding adapter file. For
example, we may define an object named ``vehicle`` and save it in a
``vehicle.lgt`` source file that will be compiled to a
``vehicle_lgt.pl`` Prolog file. If we have a ``sort(_)`` parametric
object we can save it on a ``sort_1.lgt`` source file that will be
compiled to a ``sort_1_lgt.pl`` Prolog file. This name scheme helps
avoid file name conflicts (remember that all Logtalk entities share the
same namespace). To further prevent file name conflicts, specially when
embedding applications, and depending on the backend compiler, the names
of the intermediate Prolog files may include a directory hash.

Logtalk source files may contain Prolog code interleaved with Logtalk
entity definitions. Plain Prolog code is usually copied as-is to the
corresponding Prolog output file (except, of course, if subject to the
term-expansion mechanism). Prolog modules are compiled as objects. The
following Prolog directives are processed when read (thus affecting the
compilation of the source code that follows): ``ensure_loaded/1``,
``use_module/1-2``, ``op/3``, and ``set_prolog_flag/2``. The
``initialization/1`` Prolog directive may be used for defining an
initialization goal to be executed when loading a source file. Most
calls to Logtalk built-in predicates from file ``initialization/1``
directives are compiled for better performance.

The text encoding used in a source file may be declared using the
:ref:`directives_encoding_1` directive when running Logtalk with
backend Prolog compilers that support multiple encodings (check the
:ref:`encoding_directive <flag_encoding_directive>` flag in the
adapter file of your Prolog compiler).

Logtalk source files can include the text of other files by using the
:ref:`directives_include_1` directive.
Although there is also a standard Prolog ``include/1`` directive, any
occurrences of this directive in a Logtalk source file is handled by
the Logtalk compiler, not by the backend Prolog compiler.

.. _programming_portability:

Portable applications
~~~~~~~~~~~~~~~~~~~~~

Logtalk is compatible with most modern standards compliant Prolog compilers.
However, this does not necessarily imply that your Logtalk applications will
have the same level of portability. If possible, you should only use in your
applications Logtalk built-in predicates and ISO Prolog specified
built-in predicates and arithmetic functions. If you need to use
built-in predicates (or built-in arithmetic functions) that may not be
available in other Prolog compilers, you should try to encapsulate the
non-portable code in a small number of objects and provide a portable
**interface** for that code through the use of Logtalk protocols. An
example will be code that access operating-system specific features. The
Logtalk compiler can warn you of the use of non-ISO specified built-in
predicates and arithmetic functions by using the
:ref:`portability <flag_portability>` compiler flag.

.. _programming_cc:

Conditional compilation
~~~~~~~~~~~~~~~~~~~~~~~

Logtalk supports conditional compilation within source files using the
:ref:`directives_if_1`, :ref:`directives_elif_1`,
:ref:`directives_else_0`, and :ref:`directives_endif_0` directives. This
support is similar to the support found in several Prolog systems such
as ECLiPSe, GNU Prolog, SICStus Prolog, SWI-Prolog, XSB, and YAP.

.. _programming_errors:

Avoiding common errors
~~~~~~~~~~~~~~~~~~~~~~

Try to write objects and protocol documentation **before** writing any
other code; if you are having trouble documenting a predicate perhaps we
need to go back to the design stage.

Try to avoid lengthy hierarchies. Composition is often a better choice
over inheritance for defining new objects (Logtalk supports
component-based programming through the use of
:ref:`categories <categories_categories>`). In addition, prototype-based
hierarchies are semantically simpler than class-based hierarchies.

Dynamic predicates or dynamic entities are sometimes needed, but we
should always try to minimize the use of non-logical features such as
asserts and retracts.

Since each Logtalk entity is independently compiled, if an object
inherits a dynamic or a meta-predicate predicate, then the respective
directives must be repeated to ensure a correct compilation.

In general, Logtalk does not verify if a user predicate call/return
arguments comply with the declared modes. On the other hand, Logtalk
built-in predicates, built-in methods, and message sending control
structures are fully checked for calling mode errors.

Logtalk error handling strongly depends on the ISO compliance of the
chosen Prolog compiler. For instance, the error terms that are generated
by some Logtalk built-in predicates assume that the Prolog built-in
predicates behave as defined in the ISO standard regarding error
conditions. In particular, if your Prolog compiler does not support a
``read_term/3`` built-in predicate compliant with the ISO Prolog
Standard definition, then the current version of the Logtalk compiler
may not be able to detect misspell variables in your source code.

.. _programming_style:

Coding style guidelines
~~~~~~~~~~~~~~~~~~~~~~~

It is suggested that all code between an entity opening and closing
directives be indented by one tab stop. When defining entity code, both
directives and predicates, Prolog coding style guidelines may be
applied. All Logtalk source files, examples, and standard library
entities use tabs (the recommended setting is a tab width equivalent to
4 spaces) for laying out code. Closed related entities can be defined in
the same source file. However, for best performance, is often necessary
to have an entity per source file. Entities that might be useful in
different contexts (such as library entities) are best defined in their
own source files.

.. _programming_session:

Compiling and running applications
----------------------------------

We run Logtalk inside a normal Prolog session, after loading the
necessary files. Logtalk extends but does not modify your Prolog
compiler. We can freely mix Prolog queries with the sending of messages
and our applications can be made of both normal Prolog clauses and
object definitions.

.. _programming_starting:

Starting Logtalk
~~~~~~~~~~~~~~~~

Depending on your Logtalk installation, you may use a script or a
shortcut to start Logtalk with your chosen Prolog compiler. On POSIX
operating systems, the scripts should be available from the
command-line; scripts are named upon the used Prolog compilers. On
Windows, the shortcuts should be available from the Start Menu. If no
scripts or shortcuts are available for your installation,
operating-system, or Prolog compiler, you can always start a Logtalk
session by performing the following steps:

#. Start your Prolog compiler.
#. Load the appropriate adapter file for your compiler. Adapter files
   for most common Prolog compilers can be found in the ``adapters``
   subdirectory.
#. Load the library paths file corresponding to your Logtalk
   installation contained in the ``paths`` subdirectory.
#. Load the Logtalk compiler/runtime files contained in the ``compiler``
   subdirectory.

Note that the adapter files, compiler/runtime files, and library paths
file are Prolog source files. The predicate called to load (and compile)
them depends on your Prolog compiler. In case of doubt, consult your
Prolog compiler reference manual or take a look at the definition of the
predicate ``'$lgt_load_prolog_code'/3`` in the corresponding adapter
file.

Most Prolog compilers support automatic loading of an initialization
file, which can include the necessary directives to load both the Prolog
adapter file and the Logtalk compiler. This feature, when available,
allows automatic loading of Logtalk when you start your Prolog compiler.

.. _programming_compiling:

Compiling and loading your applications
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Your applications will be made of source files containing your objects,
protocols, and categories. The source files can be compiled to disk by
calling the :ref:`predicates_logtalk_compile_1` built-in predicate:

.. code-block:: text

   | ?- logtalk_compile([source_file1, source_file2, ...]).

This predicate runs the compiler on each file and, if no fatal errors
are found, outputs Prolog source files that can then be consulted or
compiled in the usual way by your Prolog compiler.

To compile to disk and also load into memory the source files we can use
the :ref:`predicates_logtalk_load_1` built-in predicate:

.. code-block:: text

   | ?- logtalk_load([source_file1, source_file2, ...]).

This predicate works in the same way of the predicate
``logtalk_compile/1`` but also loads the compiled files into memory.

Both predicates expect a source file name or a list of source file names
as an argument. The Logtalk source file name extension, as defined in
the adapter file (by default, ``.lgt``), can be omitted.

If you have more than a few source files then you may want to use a
loader helper file containing the calls to the ``logtalk_load/1-2``
predicates. Consulting or compiling the loader file will then compile
and load all your Logtalk entities into memory (see below for details).

With most Prolog backend compilers, you can use the shorthands
``{File}`` for ``logtalk_load(File)`` and ``{File1, File2, ...}`` for
``logtalk_load([File1, File2, ...])``. The use these shorthands should
be restricted to the Logtalk/Prolog top-level interpreter as they are
not part of the language specification and may be commented out in case
of conflicts with backend Prolog compiler features.

The built-in predicate :ref:`predicates_logtalk_make_0` can be
used to reload all modified source files. Files are also reloaded when
the compilation mode changes. For example, assume that you have loaded
your application files and found a bug. You can easily recompile the
files in debug mode by using the queries:

.. code-block:: text

   | ?- set_logtalk_flag(debug, on).
   ...

   | ?- logtalk_make.
   ...

After debugging and fixing the bugs, you can reload the files in normal
(or optimized) mode by turning the :ref:`debug <flag_debug>` flag off and
calling the ``logtalk_make/0`` predicate again. With most backend Prolog
compilers, you can also use the ``{*}`` top-level shortcut.

An extended version of this predicate, :ref:`predicates_logtalk_make_1`,
accepts multiple targets including ``all``, ``clean``, ``check``,
``circular``, ``documentation``, and ``caches``. See the reference manual
for a complete list of targets and top-level shortcuts. In particular, the
``logtalk_make(clean)`` goal can be specially useful before switching
backend Prolog compilers as the generated intermediate files may not be
compatible. The ``logtalk_make(caches)`` goal is usually used when
benchmarking compiler performance improvements.

.. _programming_loaders:

Loader utility files
~~~~~~~~~~~~~~~~~~~~

Most examples directories contain a Logtalk utility file that can be
used to load all included source files. These loader utility files are
usually named ``loader.lgt`` or contain the word "loader" in their name.
Loader files are ordinary source file and thus compiled and loaded like
any source file. For an example loader file named ``loader.lgt`` we
would type:

.. code-block:: text

   | ?- logtalk_load(loader).

Usually these files contain a call to the built-in predicates
:ref:`predicates_set_logtalk_flag_2`
(e.g. for setting global, *project-specific*, flag values) and
:ref:`predicates_logtalk_load_1` or :ref:`predicates_logtalk_load_2` (for
loading project files), wrapped inside a Prolog ``initialization/1``
directive. For instance, if your code is split in three Logtalk source
files named ``source1.lgt``, ``source2.lgt``, and ``source3.lgt``, then
the contents of your loader file could be:

::

   :- initialization((
       % set project-specific global flags
       set_logtalk_flag(events, allow),
       % load the project source files
       logtalk_load([source1, source2, source3])
   )).

Another example of directives that are often used in a loader file would
be ``op/3`` directives declaring global operators needed by your
application. Loader files are also often used for setting source
file-specific compiler flags (this is useful even when you only have a
single source file if you always load it with using the same set of
compiler flags). For example:

::

   :- initialization((
       % set project-specific global flags
       set_logtalk_flag(underscore_variables, dont_care),
       set_logtalk_flag(source_data, off),
       % load the project source files
       logtalk_load(
           [source1, source2, source3],
           % source file-specific flags
           [portability(warning)]),
       logtalk_load(
           [source4, source5],
           % source file-specific flags
           [portability(silent)])
   )).

To take the best advantage of loader files, define a clause for the
multifile and dynamic ``logtalk_library_path/2`` predicate for the
directory containing your source files as explained in the next section.

A common mistake is to try to set compiler flags using
``logtalk_load/2`` with a loader file. For example, by writing:

.. code-block:: text

   | ?- logtalk_load(loader, [optimize(on)]).

This will not work as you might expect as the compiler flags will only
be used in the compilation of the ``loader.lgt`` file itself and will
not affect the compilation of files loaded through the
``initialization/1`` directive contained on the loader file.

.. _programming_libraries:

Libraries of source files
~~~~~~~~~~~~~~~~~~~~~~~~~

Logtalk defines a *library* simply as a directory containing source
files. Library locations can be specified by defining or asserting
clauses for the dynamic and multifile predicate
:ref:`predicates_logtalk_library_path_2`. For example:

::

   :- multifile(logtalk_library_path/2).
   :- dynamic(logtalk_library_path/2).

   logtalk_library_path(shapes, '$LOGTALKUSER/examples/shapes/').

The first argument of the predicate is used as an alias for the path on
the second argument. Library aliases may also be used on the second
argument. For example:

::

   :- multifile(logtalk_library_path/2).
   :- dynamic(logtalk_library_path/2).

   logtalk_library_path(lgtuser, '$LOGTALKUSER/').
   logtalk_library_path(examples, lgtuser('examples/')).
   logtalk_library_path(viewpoints, examples('viewpoints/')).

This allows us to load a library source file without the need to first
change the current working directory to the library directory and then
back to the original directory. For example, in order to load a
``loader.lgt`` file, contained in a library named ``viewpoints``, we
just need to type:

.. code-block:: text

   | ?- logtalk_load(viewpoints(loader)). 

The best way to take advantage of this feature is to load at startup a
source file containing clauses for the ``logtalk_library_path/2``
predicate needed for all available libraries. This allows us to load
library source files or entire libraries without worrying about
libraries paths, improving code portability. The directory paths on the
second argument should always end with the path directory separator
character. Most backend Prolog compilers allows the use of environment
variables in the second argument of the ``logtalk_library_path/2``
predicate. Use of POSIX relative paths (e.g. ``'../'`` or ``'./'``) for
top-level library directories (e.g. ``lgtuser`` in the example above) is
not advised as different backend Prolog compilers may start with
different initial working directories, which may result in portability
problems of your loader files.

The library notation provides functionality inspired by the
``file_search_path/2`` mechanism introduced by Quintus Prolog and later
adopted by some other Prolog compilers.

.. _programming_linter:

Compiler linter
~~~~~~~~~~~~~~~

The compiler includes a linter that checks for a wide range of possible
problems in source files. Notably, the compiler checks for unknown
entities, unknown predicates, undefined predicates (i.e. predicates that
are declared but not defined), missing directives (including missing
``dynamic/1`` and ``meta_predicate/1`` directives), redefined built-in
predicates, calls to non-portable predicates, singleton variables,
tautology and falsehood goals (i.e. goals that are can be replaced by
``true`` or ``fail``), and trivial fails (i.e. calls to predicates with
no match clauses). Some of the linter warnings are controlled by
compiler flags. See the next section for details.

.. _programming_flags:

Compiler flags
~~~~~~~~~~~~~~

The :ref:`predicates_logtalk_load_1` and :ref:`predicates_logtalk_compile_1`
always use the current set of default compiler flags as specified in
your settings file and the Logtalk adapter files or changed for the
current session using the built-in predicate
:ref:`predicates_set_logtalk_flag_2`.
Although the default flag values cover the usual cases, you may want to
use a different set of flag values while compiling or loading some of
your Logtalk source files. This can be accomplished by using the
:ref:`predicates_logtalk_load_2` or the :ref:`predicates_logtalk_compile_2`
built-in predicates. These two predicates accept a list of options
affecting how a Logtalk source file is compiled and loaded:

.. code-block:: text

   | ?- logtalk_compile(Files, Options).

or:

.. code-block:: text

   | ?- logtalk_load(Files, Options).

In fact, the ``logtalk_load/1`` and ``logtalk_compile/1`` predicates are
just shortcuts to the extended versions called with the default compiler
flag values. The options are represented by a compound term where the
functor is the flag name and the sole argument is the flag value.

We may also change the default flag values from the ones loaded from the
adapter file by using the :ref:`predicates_set_logtalk_flag_2`
built-in predicate. For example:

.. code-block:: text

   | ?- set_logtalk_flag(unknown_entities, silent).

The current default flags values can be enumerated using the
:ref:`predicates_current_logtalk_flag_2` built-in predicate:

.. code-block:: text

   | ?- current_logtalk_flag(unknown_entities, Value).

   Value = silent
   yes

Logtalk also implements a :ref:`directives_set_logtalk_flag_2`
directive, which can be used to set flags within a source file or within
an entity. For example:

::

   % compile objects in this source file with event support
   :- set_logtalk_flag(events, allow).

   :- object(foo).

       % compile this object with support
       % for dynamic predicate declarations
       :- set_logtalk_flag(dynamic_declarations, allow).
       ...

   :- end_object.

   ...

Note that the scope of the ``set_logtalk_flag/2`` directive is local to
the entity or to the source file containing it.

Version flags
^^^^^^^^^^^^^

.. index:: single: version_data flag
.. _flag_version_data:

``version_data(Value)``
   Read-only flag whose value is the compound term
   ``logtalk(Major,Minor,Patch,Status)``. The first three arguments are
   integers and the last argument is an atom, possibly empty,
   representing version status: ``aN`` for alpha versions, ``bN`` for
   beta versions, ``rcN`` for release candidates (with ``N`` being a
   natural number), and ``stable`` for stable versions. The
   ``version_data`` flag is also a de facto standard for Prolog
   compilers.

Lint flags
^^^^^^^^^^

.. index:: single: unknown_entities flag
.. _flag_unknown_entities:

``unknown_entities(Option)``
   Controls the unknown entity warnings, resulting from loading an
   entity that references some other entity that is not currently
   loaded. Possible option values are ``warning`` (the usual default)
   and ``silent``. Note that these warnings are not always avoidable,
   specially when using reflective designs of class-based hierarchies.

.. index:: single: unknown_predicates flag
.. _flag_unknown_predicates:

``unknown_predicates(Option)``
   Defines the compiler behavior when calls to unknown predicates (or
   non-terminals) are found. An unknown predicate is a called predicate
   that is neither locally declared or defined. Possible option values
   are ``error``, ``warning`` (the usual default), and ``silent`` (not
   recommended).

.. index:: single: undefined_predicates flag
.. _flag_undefined_predicates:

``undefined_predicates(Option)``
   Defines the compiler behavior when calls to declared but undefined
   predicates (or non-terminals) are found. Note that calls to declared
   but undefined predicates (or non-terminals) fail as per closed-world
   assumption. Possible option values are ``error``, ``warning`` (the
   usual default), and ``silent`` (not recommended).

.. index:: single: portability flag
.. _flag_portability:

``portability(Option)``
   Controls the non-ISO specified Prolog built-in predicate and non-ISO
   specified Prolog built-in arithmetic function calls warnings plus use
   of non-standard Prolog flags and/or flag values. Possible option
   values are ``warning`` and ``silent`` (the usual default).

.. index:: single: missing_directives flag
.. _flag_missing_directives:

``missing_directives(Option)``
   Controls the missing predicate directive warnings. Possible option
   values are ``warning`` (the usual default) and ``silent`` (not
   recommended).

.. index:: single: duplicated_directives flag
.. _flag_duplicated_directives:

``duplicated_directives(Option)``
   Controls the duplicated predicate directive warnings. Possible option
   values are ``warning`` (the usual default) and ``silent`` (not
   recommended). Note that conflicting directives for the same predicate
   are handled as errors, not as duplicated directive warnings.

.. index:: single: trivial_goal_fails flag
.. _flag_trivial_goal_fails:

``trivial_goal_fails(Option)``
   Controls the printing of warnings warnings for calls to local static
   predicates with no matching clauses. Possible option values are
   ``warning`` (the usual default) and ``silent`` (not recommended).

.. index:: single: always_true_or_false_goals flag
.. _flag_always_true_or_false_goals:

``always_true_or_false_goals(Option)``
   Controls the printing of warnings for goals that are always true or
   false. Possible option values are ``warning`` (the usual default) and
   ``silent`` (not recommended).

.. index:: single: lambda_variables flag
.. _flag_lambda_variables:

``lambda_variables(Option)``
   Controls the printing of lambda variable related warnings. Possible
   option values are ``warning`` (the usual default) and ``silent`` (not
   recommended).

.. index:: single: suspicious_calls flag
.. _flag_suspicious_calls:

``suspicious_calls(Option)``
   Controls the printing of suspicious call warnings. Possible option
   values are ``warning`` (the usual default) and ``silent`` (not
   recommended).

.. index:: single: redefined_built_ins flag
.. _flag_redefined_built_ins:

``redefined_built_ins(Option)``
   Controls the Logtalk and Prolog built-in predicate redefinition
   warnings. Possible option values are ``warning`` (the usual default)
   and ``silent``. Warnings about redefined Prolog built-in predicates
   are often the result of running a Logtalk application on several
   Prolog compilers as each Prolog compiler defines its set of built-in
   predicates.

.. index:: single: singleton_variables flag
.. _flag_singleton_variables:

``singleton_variables(Option)``
   Controls the singleton variable warnings. Possible option values are
   ``warning`` (the usual default) and ``silent`` (not recommended).

.. index:: single: underscore_variables flag
.. _flag_underscore_variables:

``underscore_variables(Option)``
   Controls the interpretation of variables that start with an
   underscore (excluding the anonymous variable) that occur once in a
   term as either don't care variables or singleton variables. Possible
   option values are ``dont_care`` and ``singletons`` (the usual
   default). Note that, depending on your Prolog compiler, the
   ``read_term/3`` built-in predicate may report variables that start
   with an underscore as singleton variables. There is no standard
   behavior, hence this option.

Optional features compilation flags
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: single: complements flag
.. _flag_complements:

``complements(Option)``
   Allows objects to be compiled with support for complementing
   categories turned off in order to improve performance and security.
   Possible option values are ``allow`` (allow complementing categories
   to override local object predicate declarations and definitions),
   ``restrict`` (allow complementing categories to add predicate
   declarations and definitions to an object but not to override them),
   and ``deny`` (ignore complementing categories; the usual default).
   This option can be used on a per-object basis. Note that changing
   this option is of no consequence for objects already compiled and
   loaded.

.. index:: single: dynamic_declarations flag
.. _flag_dynamic_declarations:

``dynamic_declarations(Option)``
   Allows objects to be compiled with support for dynamic declaration of
   new predicates turned off in order to improve performance and
   security. Possible option values are ``allow`` and ``deny`` (the
   usual default). This option can be used on a per-object basis. Note
   that changing this option is of no consequence for objects already
   compiled and loaded. This option is only checked when sending an
   :ref:`methods_asserta_1` or :ref:`methods_assertz_1` message to an
   object. Local asserting of new predicates is always allowed.

.. index:: single: events flag
.. _flag_events:

``events(Option)``
   Allows message sending calls to be compiled with or without
   :ref:`event-driven programming <events_events>` support. Possible
   option values are ``allow`` and ``deny`` (the usual default). Objects
   (and categories) compiled with this option set to ``deny`` use
   optimized code for message-sending calls that does not trigger
   events. As such, this option can be used on a per-object (or
   per-category) basis. Note that changing this option is of no
   consequence for objects already compiled and loaded.

.. index:: single: context_switching_calls flag
.. _flag_context_switching_calls:

``context_switching_calls(Option)``
   Allows context switching calls (``<</2``) to be either allowed or
   denied. Possible option values are ``allow`` and ``deny``. The
   default flag vale is ``allow``. Note that changing this option is of
   no consequence for objects already compiled and loaded.

Back-end Prolog compiler and loader flags
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: single: prolog_compiler flag
.. _flag_prolog_compiler:

``prolog_compiler(Flags)``
   List of compiler flags for the generated Prolog files. The valid
   flags are specific to the used Prolog backend compiler. The usual
   default is the empty list. These flags are passed to the backend
   Prolog compiler built-in predicate that is responsible for compiling
   to disk a Prolog file. For Prolog compilers that don't provide
   separate predicates for compiling and loading a file, use instead
   the :ref:`prolog_loader <flag_prolog_loader>` flag.

.. index:: single: prolog_loader flag
.. _flag_prolog_loader:

``prolog_loader(Flags)``
   List of loader flags for the generated Prolog files. The valid flags
   are specific to the used Prolog backend compiler. The usual default
   is the empty list. These flags are passed to the backend Prolog
   compiler built-in predicate that is responsible for loading a
   (compiled) Prolog file.

Other flags
^^^^^^^^^^^

.. index:: single: scratch_directory flag
.. _flag_scratch_directory:

``scratch_directory(Directory)``
   Sets the directory to be used to store the temporary files generated
   when compiling Logtalk source files. This directory can be specified
   using an atom or using library notation. The directory must always
   end with a slash. The default value is a sub-directory of the source
   files directory, either ``'./lgt_tmp/'`` or ``'./.lgt_tmp/'``
   (depending on the backend Prolog compiler and operating-system).
   Relative directories must always start with ``'./'`` due to the lack
   of a portable solution to check if a path is relative or absolute.

.. index:: single: report flag
.. _flag_report:

``report(Option)``
   Controls the default printing of messages. Possible option values are
   ``on`` (by usual default, print all messages that are not intercepted
   by the user), ``warnings`` (only print warning and error messages
   that are not intercepted by the user), and ``off`` (do not print any
   messages that are not intercepted by the user).

.. index:: single: code_prefix flag
.. _flag_code_prefix:

``code_prefix(Character)``
   Enables the definition of prefix for all functors of Prolog code
   generated by the Logtalk compiler. The option value must be a single
   character atom. Its default value is ``'$'``. Specifying a code
   prefix provides a way to solve possible conflicts between Logtalk
   compiled code and other Prolog code. In addition, some Prolog
   compilers automatically hide predicates whose functor start with a
   specific prefix such as the character ``$``. Although this is not a
   read-only flag, it should only be changed at startup time and before
   loading any source files.

.. index:: single: optimize flag
.. _flag_optimize:

``optimize(Option)``
   Controls the compiler optimizations. Possible option values are
   ``on`` (used by default for deployment) and ``off`` (used by default
   for development). Compiler optimizations include the use of static
   binding whenever possible, the removal of redundant calls to
   ``true/0`` from predicate clauses, the removal of redundant
   unifications when compiling grammar rules, and inlining of predicate
   definitions with a single clause that links to a local predicate, to
   a plain Prolog built-in (or foreign) predicate, or to a Prolog module
   predicate with the same arguments. Care should be taken when
   developing applications with this flag turned on as changing and
   reloading a file may render :term:`static binding` optimizations
   invalid for code defining in other loaded files. Turning on this
   flag automatically turns off the :ref:`debug <flag_debug>` flag.

.. index:: single: source_data flag
.. _flag_source_data:

``source_data(Option)``
   Defines how much information is retained when compiling a source
   file. Possible option values are ``on`` (the usual default for
   development) and ``off``. With this flag set to ``on``, Logtalk will
   keep the information represented using documenting directives plus
   source location data (including source file names and line numbers).
   This information can be retrieved using reflection and is useful for
   documenting, debugging, and integration with third-party development
   tools. This flag can be turned off in order to generate more compact
   code.

.. index:: single: debug flag
.. _flag_debug:

``debug(Option)``
   Controls the compilation of source files in debug mode (the Logtalk
   default debugger can only be used with files compiled in this mode).
   Also controls, by default, printing of ``debug>`` and
   ``debug(Topic)`` messages. Possible option values are ``on`` and
   ``off`` (the usual default). Turning on this flag automatically turns
   off the :ref:`optimize <flag_optimize>` flag.

.. index:: single: reload flag
.. _flag_reload:

``reload(Option)``
   Defines the reloading behavior for source files. Possible option
   values are ``skip`` (skip loading of already loaded files; this value
   can be used to get similar functionality to the Prolog directive
   ``ensure_loaded/1`` but should be used only with fully debugged
   code), ``changed`` (the usual default; reload files only when they
   are changed since last loaded provided that the any explicit flags
   and the compilation mode are the same as before), and ``always``
   (always reload files).

.. index:: single: relative_to flag
.. _flag_relative_to:

``relative_to(Directory)``
   Defines a base directory for resolving relative source file paths.
   The default value is the directory of the source file being compiled.

.. index:: single: hook flag
.. _flag_hook:

``hook(Object)``
   Allows the definition of compiler hooks that are called for each term
   read form a source file and for each compiled goal. This option
   specifies an object (which can be the pseudo-object
   :ref:`user <apis:user/0>`) implementing the
   :ref:`expanding <apis:expanding/0>` built-in
   protocol. The hook object must be compiled and loaded when this option
   is used. It's also possible to specify a Prolog module instead of a
   Logtalk object but the module must be pre-loaded and its identifier
   must be different from any object identifier. The object is expected
   to define clauses for the :ref:`methods_term_expansion_2` and
   :ref:`methods_goal_expansion_2`
   predicates. In the case of the ``term_expansion/2`` predicate, the
   first argument is the term read form the source file while the second
   argument returns a list of terms corresponding to the expansion of
   the first argument. In the case of the ``goal_expansion/2``
   predicate, the second argument should be a goal resulting from the
   expansion of the goal in the first argument. The predicate
   ``goal_expansion/2`` is recursively called on the expanded goal until
   a fixed point is reached. Care must be taken to avoid compilation
   loops.

.. index:: single: clean flag
.. _flag_clean:

``clean(Option)``
   Controls cleaning of the intermediate Prolog files generated when
   compiling Logtalk source files. Possible option values are ``off``
   and ``on`` (the usual default). When turned on, this flag also forces
   recompilation of all source files, disregarding any existing
   intermediate files. Thus, it is strong advisable to turn on this flag
   when switching backend Prolog compilers as the intermediate files
   generated by the compilation of source files may not be portable (due
   to differences in the implementation of the standard
   ``write_canonical/2`` predicate).

User-defined flags
^^^^^^^^^^^^^^^^^^

Logtalk provides a :ref:`predicates_create_logtalk_flag_3`
predicate that can be used for defining new flags.

.. _programming_smart:

Reloading and smart compilation of source files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

As a general rule, reloading source files should never occur in
production code and should be handled with care in development code.
Reloading a Logtalk source file usually requires reloading the
intermediate Prolog file that is generated by the Logtalk compiler. The
problem is that there is no standard behavior for reloading Prolog
files. For static predicates, almost all Prolog compilers replace the
old definitions with the new ones. However, for dynamic predicates, the
behavior depends on the Prolog compiler. Most compilers replace the old
definitions but some of them simply append the new ones, which usually
leads to trouble. See the compatibility notes for the backend Prolog
compiler you intend to use for more information. There is an additional
potential problem when using multi-threading programming. Reloading a
threaded object does not recreate from scratch its old message queue,
which may still be in use (e.g. threads may be waiting on it).

When using library entities and stable code, you can avoid reloading the
corresponding source files (and, therefore, recompiling them) by setting
the :ref:`reload <flag_reload>` compiler flag to ``skip``. For code under
development, you can turn off the :ref:`clean <flag_clean>` flag to avoid
recompiling files that have not been modified since last compilation
(assuming that backend Prolog compiler that you are using supports
retrieving of file modification dates). You can disable deleting the
intermediate files generated when compiling source files by changing the
default flag value in your settings file, by using the corresponding
compiler flag with the compiling and loading built-in predicates, or,
for the remaining of a working session, by using the call:

.. code-block:: text

   | ?- set_logtalk_flag(clean, off).

Some caveats that you should be aware. First, some warnings that might
be produced when compiling a source file will not show up if the
corresponding object file is up-to-date because the source file is not
being (re)compiled. Second, if you are using several Prolog compilers
with Logtalk, be sure to perform the first compilation of your source
files with smart compilation turned off: the intermediate Prolog files
generated by the Logtalk compiler may be not compatible across Prolog
compilers or even for the same Prolog compiler across operating systems
(e.g. due to the use of different character encodings or end-of-line
characters).

.. _programming_batch:

Using Logtalk for batch processing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you use Logtalk for batch processing, you probably want to turn off
the :ref:`report <flag_report>` flag to suppress all messages of type
``banner``, ``comment``, ``comment(_)``, ``warning``, and ``warning(_)``
that are normally printed. Note that error messages and messages providing
information requested by the user will still be printed.

.. _programming_performance:

Optimizing performance
~~~~~~~~~~~~~~~~~~~~~~

The default compiler flag settings are appropriated for the
**development** but not necessarily for the **deployment** of
applications. To minimize the generated code size, turn the
:ref:`source_data <flag_source_data>` flag off. To optimize runtime
performance, turn on the :ref:`optimize <flag_optimize>` flag.
Your chosen backend Prolog compiler may also provide performance
related flags; check its documentation.

Pay special attention to file compilation/loading order. Whenever
possible, compile/load your files taking into account file dependencies
to enable :term:`static binding` optimizations. The easiest way to find
the dependencies and thus the best compilation/loading order is to use
the ``diagrams`` tool to generate a file dependency diagram for your
application.

Minimize the use of dynamic predicates. Parametric objects can often be
used in alternative. When dynamic predicates cannot be avoided, try to
make them private. Declaring a dynamic predicate also as a private
predicate allows the compiler to optimize local calls to the database
methods (e.g. :ref:`methods_assertz_1` and :ref:`methods_retract_1`) that
handle the predicate.

Sending a :term:`message to self` implies :term:`dynamic binding` but
there are often cases where :ref:`control_send_to_self_1` is misused
to call an imported or inherited predicate that is never going to be
redefined in a descendant. In these cases, a :term:`super call`,
:ref:`control_call_super_1`, can be used instead with
the benefit of often enabling static binding. Most of the guidelines for
writing efficient Prolog code also apply to Logtalk code. In particular,
define your predicates to take advantage of first-argument indexing. In
the case of recursive predicates, define them as tail-recursive predicates
whenever possible.

.. _programming_debugging:

Debugging applications
----------------------

The Logtalk distribution includes in its ``tools`` directory a
command-line debugger, implemented as a Logtalk application. It can be
loaded by typing:

.. code-block:: text

   | ?- logtalk_load(debugger(loader)).

This tool implements debugging features similar to those found on most
Prolog systems. There are some differences, however, between the usual
implementation of Prolog debuggers and the current implementation of the
Logtalk debugger that you should be aware. First, unlike some Prolog
debuggers, the Logtalk debugger is not built-in but a regular Logtalk
application using documented debugging hook predicates. This translates
to a different, although similar, set of debugging features when compared
with some of the more sophisticated Prolog debuggers. Second, debugging is
only possible for entities compiled in debug mode. When compiling an entity
in debug mode, Logtalk decorates clauses with source information to allow
tracing of the goal execution. Third, implementation of spy points allows
the user to specify the execution context for entering the debugger. This
feature is a consequence of the encapsulation of predicates inside objects.

.. _programming_debug_mode:

Compiling source files and entities in debug mode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Compilation of source files in debug mode is controlled by the
:ref:`debug <flag_debug>` compiler flag. The default value for this flag,
usually ``off``, is defined in the adapter files. Its default value may
be changed at runtime by calling:

.. code-block:: text

   | ?- set_logtalk_flag(debug, on).

In alternative, if we want to compile only some source files in debug
mode, we may instead write:

.. code-block:: text

   | ?- logtalk_load([file1, file2, ...], [debug(on)]).

The :ref:`predicates_logtalk_make_1` built-in predicate can also be used to
recompile all loaded files (that were loaded in normal mode) in debug mode:

.. code-block:: text

   | ?- logtalk_make(debug).

With most backend Prolog compilers, the ``{+d}`` top-level shortcut can also
be used.

The :ref:`clean <flag_clean>` compiler flag should be turned on whenever
the :ref:`debug <flag_debug>` flag is turned on at runtime. This is necessary
because debug code would not be generated for files previously compiled in
normal mode if there are no changes to the source files.

After loading the debugger, we may check (or enumerate by backtracking),
all loaded entities compiled in debug mode as follows:

.. code-block:: text

   | ?- debugger::debugging(Entity).

To compile only a specific entity in debug mode, use the
:ref:`directives_set_logtalk_flag_2` directive inside the entity.

.. _programming_box_model:

Logtalk Procedure Box model
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Logtalk uses a *Procedure Box model* similar to those found on most
Prolog compilers. The traditional Prolog procedure box model defines
four ports (*call*, *exit*, *redo*, and *fail*) for describing control
flow when a predicate clause is used during program execution:

| ``call``
|    predicate call
| ``exit``
|    success of a predicate call
| ``redo``
|    backtracking into a predicate
| ``fail``
|    failure of a predicate call

Logtalk, as found on some recent Prolog compilers, adds a port for
dealing with exceptions thrown when calling a predicate:

| ``exception``
|    predicate call throws an exception

In addition to the ports described above, Logtalk adds two more ports,
``fact`` and ``rule``, which show the result of the unification of a
goal with, respectively, a fact and a rule head:

| ``fact``
|    unification success between a goal and a fact
| ``rule``
|    unification success between a goal and a rule head

Following Prolog tradition, the user may define for which ports the
debugger should pause for user interaction by specifying a list of
*leashed* ports. For example:

.. code-block:: text

   | ?- debugger::leash([call, exit, fail]).

Alternatively, the user may use an atom abbreviation for a pre-defined
set of ports. For example:

.. code-block:: text

   | ?- debugger::leash(loose).

The abbreviations defined in Logtalk are similar to those defined on
some Prolog compilers:

| ``none``
|    ``[]``
| ``loose``
|    ``[fact, rule, call]``
| ``half``
|    ``[fact, rule, call, redo]``
| ``tight``
|    ``[fact, rule, call, redo, fail, exception]``
| ``full``
|    ``[fact, rule, call, exit, redo, fail, exception]``

By default, the debugger pauses at every port for user interaction.

Defining spy points
~~~~~~~~~~~~~~~~~~~

Logtalk spy points can be defined by simply stating which file line
numbers or predicates should be spied, as in most Prolog debuggers, or
by fully specifying the context for activating a spy point. In the case
of line number spy points (also known as breakpoints), the line number
must correspond to the first line of an entity clause. To simplify the
definition of line number spy points, these are specified using the
entity identifier instead of the file name (as all entities share a
single namespace, an entity can only be defined in a single file).

Defining line number and predicate spy points
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Line number and predicate spy points are specified using the debuuger
``spy/1`` predicate. The argument can be a breakpoint (expressed as a
``Entity-Line`` pair), a predicate indicator (``Name/Arity``), or a
list of spy points. For example:

.. code-block:: text

   | ?- debugger::spy(person-42).

   Spy points set.
   yes

   | ?- debugger::spy(foo/2).

   Spy points set.
   yes

   | ?- debugger::spy([foo/4, bar/1]).

   Spy points set.
   yes

Line numbers and predicate spy points can be removed by using the
debugger ``nospy/1`` predicate. The argument can be a spy point, a
list of spy points, or a non-instantiated variable in which case all
spy points will be removed. For example:

.. code-block:: text

   | ?- debugger::nospy(_).

   All matching predicate spy points removed.
   yes

Defining context spy points
^^^^^^^^^^^^^^^^^^^^^^^^^^^

A context spy point is a tuple describing a message execution context and
a goal:

::

   (Sender, This, Self, Goal)

The debugger is evoked whenever the execution context is true and when
the spy point goal unifies with the goal currently being executed.
Variable bindings resulting from the unification between the current
goal and the goal argument are discarded. The user may establish any
number of context spy points as necessary. For example, in order to call
the debugger whenever a predicate defined on an object named ``foo`` is
called we may define the following spy point:

.. code-block:: text

   | ?- debugger::spy(_, foo, _, _).

   Spy point set.
   yes

For example, we can spy all calls to a ``foo/2`` predicate by setting
the condition:

.. code-block:: text

   | ?- debugger::spy(_, _, _, foo(_, _)).

   Spy point set.
   yes

The debugger ``nospy/4`` predicate may be used to remove all matching
spy points. For example, the call:

.. code-block:: text

   | ?- debugger::nospy(_, _, foo, _).

   All matching context spy points removed.
   yes

will remove all context spy points where the value of :term:`self` matches the
atom ``foo``.

Removing all spy points
^^^^^^^^^^^^^^^^^^^^^^^

We may remove all line number, predicate, and context spy points by
using the debugger ``nospyall/0`` predicate:

.. code-block:: text

   | ?- debugger::nospyall.

   All line number spy points removed.
   All predicate spy points removed.
   All context spy points removed.
   yes

.. _programming_trace:

Tracing program execution
~~~~~~~~~~~~~~~~~~~~~~~~~

Logtalk allows tracing of execution for all objects compiled in debug
mode. To start the debugger in trace mode, write:

.. code-block:: text

   | ?- debugger::trace.

   yes

Note that, when tracing, spy points will be ignored. While tracing, the
debugger will pause for user input at each leashed port, printing an
informative message with the port name and the current goal. Before the
port number, when a spy point is set for the current clause or goal, the
debugger will print a ``#`` character for line number spy points, a
``+`` character for predicate spy points, and a ``*`` character for
context spy points. The debugger also provides determinism information
by prefixing the ``exit`` port with a ``*`` character when a call
succeeds with choice-points pending. After the port name, the debugger
prints the goal invocation number. This invocation number is unique and
can be used to correlate the port trace messages.

To stop tracing and turning off the debugger, write:

.. code-block:: text

   | ?- debugger::notrace.

   yes

.. _programming_debug:

Debugging using spy points
~~~~~~~~~~~~~~~~~~~~~~~~~~

Tracing a program execution may generate large amounts of debugging
data. Debugging using spy points allows the user to concentrate its
attention in specific points of its code. To start a debugging session
using spy points, write:

.. code-block:: text

   | ?- debugger::debug.

   yes

At the beginning of a port description, the debugger will print a ``#``,
``+``, or ``*`` character before the current goal if there is,
respectively, a line number, a predicate, or a context spy point
defined.

To stop the debugger, write:

::

   | ?- debugger::nodebug.

   yes

Note that stopping the debugger does not remove any defined spy points.

.. _programming_commands:

Debugging commands
~~~~~~~~~~~~~~~~~~

The debugger pauses at leashed ports when tracing or when finding a spy
point for user interaction. The commands available are as follows:

``c`` — creep
   go on; you may use the spacebar, return, or enter keys in alternative
``l`` — leap
   continues execution until the next spy point is found
``s`` — skip
   skips debugging for the current goal; valid at call, redo, and
   unification ports
``q`` — quasi-skip
   skips debugging until returning to the current goal or reaching a spy
   point; valid at call and redo ports
``r`` — retry
   retries the current goal but side-effects are not undone; valid at
   the fail port
``j`` — jump
   reads invocation number and continues execution until a port is
   reached for that number
``z`` — zap
   reads port name and continues execution until that port is reached
   reads negated port name and continues execution until a port other
   than the negated port is reached
``i`` — ignore
   ignores goal, assumes that it succeeded; valid at call and redo ports
``f`` — fail
   forces backtracking; may also be used to convert an exception into a
   failure
``n`` — nodebug
   turns off debugging
``@`` — command; ``!`` can be used in alternative
   reads and executes a query
``b`` — break
   suspends execution and starts new interpreter; type ``end_of_file``
   to terminate
``a`` — abort
   returns to top level interpreter
``Q`` — quit
   quits Logtalk
``p`` — print
   writes current goal using the print/1 predicate if available
``d`` — display
   writes current goal without using operator notation
``w`` — write
   writes current goal quoting atoms if necessary
``$`` — dollar
   outputs the compiled form of the current goal (for low-level
   debugging)
``x`` — context
   prints execution context
``.`` — file
   prints file, entity, predicate, and line number information at an
   unification port
``e`` — exception
   prints exception term thrown by the current goal
``=`` — debugging
   prints debugging information
``<`` — write depth
   sets the write term depth (set to 0 to reset)
``*`` — add
   adds a context spy point for the current goal
``/`` — remove
   removes a context spy point for the current goal
``+`` — add
   adds a predicate spy point for the current goal
``-`` — remove
   removes a predicate spy point for the current goal
``#`` — add
   adds a line number spy point for the current clause
``|`` — remove
   removes a line number spy point for the current clause
``h`` — condensed help
   prints list of command options
``?`` — extended help
   prints list of command options

.. _programming_context:

Context-switching calls
~~~~~~~~~~~~~~~~~~~~~~~

Logtalk provides a control construct, :ref:`control_context_switch_2`, which allows the
execution of a query within the context of an object. Common debugging
uses include checking an object local predicates (e.g. predicates
representing internal dynamic state) and sending a message from within
an object. This control construct may also be used to write unit tests.

Consider the following toy example:

::

   :- object(broken).

       :- public(a/1).

       a(A) :- b(A, B), c(B).
       b(1, 2). b(2, 4). b(3, 6).
       c(3).

   :- end_object.

Something is wrong when we try the object public predicate, ``a/1``:

.. code-block:: text

   | ?- broken::a(A).

   no

For helping diagnosing the problem, instead of compiling the object in
debug mode and doing a *trace* of the query to check the clauses for the
non-public predicates, we can instead simply type:

.. code-block:: text

   | ?- broken << c(C).

   C = 3
   yes

The ``<</2`` control construct works by switching the execution context
to the object in the first argument and then compiling and executing the
second argument within that context:

.. code-block:: text

   | ?- broken << (self(Self), sender(Sender), this(This)).

   Self = broken
   Sender = broken
   This = broken

   yes

As exemplified above, the ``<</2`` control construct allows you to call
an object local and private predicates. However, it is important to
stress that we are not bypassing or defeating an object predicate scope
directives. The calls take place within the context of the specified
object, not within the context of the object making the ``<</2`` call.
Thus, the ``<</2`` control construct implements a form of
*execution-context switching*.

The availability of the ``<</2`` control construct is controlled by the
:ref:`context_switching_calls <flag_context_switching_calls>` compiler
flag (its default value is defined in the adapter files of the backend
Prolog compilers).

.. _programming_hooks:

Using compilation hooks and term expansion for debugging
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It is possible to use compilation hooks and the term expansion mechanism
for conditional compilation of debugging goals. Assume that we chose the
predicate ``debug/1`` to represent debug goals. For example:

::

   member(Head, [Head| _]) :-
       debug((write('Base case: '), writeq(member(Head, [Head| _])))).
   member(Head, [_| Tail]) :-
       debug((write('Recursive case: '), writeq(member(Head, Tail)))),
       member(Head, Tail).

When debugging, we want to call the argument of the predicate
``debug/1``. This can be easily accomplished by defining a hook object
containing the following definition for ``goal_expansion/2``:

::

   goal_expansion(debug(Goal), Goal).

When not debugging, we can use a second hook object to discard the
``debug/1`` calls by defining the predicate ``goal_expansion/2`` as
follows:

::

   goal_expansion(debug(_), true).

The Logtalk compiler automatically removes any redundant calls to the
built-in predicate ``true/0`` when compiling object predicates.

.. _programming_debugging_messages:

Debugging messages
~~~~~~~~~~~~~~~~~~

Calls to the ``logtalk::print_message/3`` predicate where the message
kind is either ``debug`` or ``debug(_)`` are only printed, by default,
when the :ref:`debug <flag_debug>` flag is turned on. Note that using
these messages does not require compiling the code in debug mode, only
turning on the flag. To avoid having to define
:ref:`methods_message_tokens_2` grammar rules for
translating each debug message, Logtalk provides default tokenization
for four *meta-messages* that cover the most common cases:

``@Message``
   By default, the message is printed as passed to the ``write/1``
   predicate followed by a newline.
``Key-Value``
   By default, the message is printed as ``Key: Value`` followed by a
   newline. The value is printed as passed to the ``writeq/1``
   predicate.
``List``
   By default, the list items are printed indented one per line. The
   items are preceded by a dash and printed as passed to the
   ``writeq/1`` predicate.
``Title::List``
   By default, the title is printed followed by a newline and the
   indented list items, one per line. The items are preceded by a dash
   and printed as passed to the ``writeq/1`` predicate.

These print messages goals can always be combined with hooks as
described in the previous section to remove them in production ready
code. Some simple examples of using these meta-messages:

.. code-block:: text

   | ?- logtalk::print_message(debug, core, @'Phase 1 completed').
   yes

   | ?- set_logtalk_flag(debug, on).
   yes

   | ?- logtalk::print_message(debug, core, @'Phase 1 completed').
   >>> Phase 1 completed
   yes

   | ?- logtalk::print_message(debug, core, answer-42).
   >>> answer: 42
   yes

   | ?- logtalk::print_message(debug, core, [arthur,ford,marvin]).
   >>> - arthur
   >>> - ford
   >>> - marvin
   yes

   | ?- logtalk::print_message(debug, core, names::[arthur,ford,marvin]).
   >>> names:
   >>> - arthur
   >>> - ford
   >>> - marvin
   yes
