This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/Logtalk/manuals/userman/programming.html
pmoura 755c60a7ca Logtalk 2.22.5 files.
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1244 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
2005-02-10 00:02:06 +00:00

184 lines
14 KiB
HTML

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/css" href="../styles.css" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>Logtalk user manual: programming in Logtalk</title>
<link rel="stylesheet" href="../styles.css" type="text/css" />
</head>
<body>
<div class="navtop">
<a href="../index.html">contents</a> &gt; <a href="index.html">user manual</a>
</div>
<h1>Programming in Logtalk</h1>
<h2>Writing programs<a name="writing"></a></h2>
<p>
For a successful programming in Logtalk, you need a good working knowledge of Prolog and an understanding of the principles of object-oriented programming. All 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.
</p>
<p>
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 <a href="../bibliography.html#Champaux92">[Champaux 92]</a> in Prolog programming. That said, writing programs in Logtalk is similar to writing programs 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.
</p>
<h3>Source files<a name="source_files"></a></h3>
<p>
A Logtalk source file must contain only one entity, either an object, a category, or a protocol. It is recommended that each 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 <code>.lgt</code> but this is optional and can be set in the configuration files. Compiled source files (by the Logtalk preprocessor) have, by default, a <code>.pl</code> extension. Again, this can be set to match the needs of a particular Prolog compiler in the corresponding configuration file. For example, we may define an object named <code>vehicle</code> and save it in a <code>vehicle.lgt</code> source file that will be compiled to a <code>vehicle.pl</code> Prolog file. If we have a <code>sort(_)</code> parametric object we can save it on a <code>sort1.lgt</code> source file that will be compiled to a <code>sort1.pl</code> Prolog file. This name scheme helps avoid file name conflicts (remember that all Logtalk entities share the same name space).
</p>
<p>
Any Logtalk source file can contain arbitrary directives and clauses before the opening entity directive. These directives and clauses will not be compiled by the Logtalk preprocessor and will be copied unchanged to the beginning of the corresponding Prolog output file. This feature is included to help the integration of Logtalk with other Prolog extensions such as, for example, constraint programming extensions.
</p>
<h3>Source metafiles<a name="source_metafiles"></a></h3>
<p>
Sometimes is useful to be able to define several entities in the same source file. This can be accomplished by using Logtalk <em>source metafiles</em>. Logtalk source metafiles are identified by the extension <code>.mlgt</code>. A metafile can be interpreted as the concatenation of source files. Logtalk compiles a source metafile by automatically splitting it into individual entity source files. In addition, two helper files for compiling and loading the extracted entity files are generated. The names of these helper files are the concatenation of the metafile name with the sufixes <code>_load</code> and <code>_compile</code>. Both helper files use the extension <code>.lgt</code>. For example, splitting a metafile named <code>my_program.mlgt</code> results in helper files named <code>my_program_compile.mlgt</code> and <code>my_program_load.lgt</code>.
</p>
<p>
Source metafiles may be compiled and loaded in the same way as single-entity source files by using the Logtalk built-in predicates <code>logtalk_compile/1-2</code> and <code>logtalk_load/1-2</code> (omitting the <code>.mlgt</code> file name extension). For example, assuming a metafile named <code>my_program.mlgt</code>, the following call:
</p>
<pre>
:- logtalk_compile(my_program).
</pre>
<p>
results in the compilation of all extracted entity files. Likewise, the call:
</p>
<pre>
:- logtalk_load(my_program).
</pre>
<p>
results in the compilation and loading of all extracted entity files. If compilation options are given (through the use of the predicates <code>logtalk_compile/2</code> or <code>logtalk_load/2</code>), these will be used in the compilation and loading of each extracted entity file.
</p>
<p>
Currently, only limited error checking is performed during extraction of individual source files from a source metafile. The extraction process is guided by the occurrence of opening and closing entity directives, with all terms being copied to the generated files without further analysis.
</p>
<p>
As with source files, clauses and directives occurring before an entity opening directive are copied unchanged to the extracted entity source file. In the unlikely event that a source metafile does not contain any entity definitions, any predicate clauses and directives it might contain are copied, unchanged, to the generated loading helper file (but not to the generated compiling helper file).
</p>
<h3>Loader utility files<a name="loaders"></a></h3>
<p>
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 <code>loader.lgt</code> or contain the word "loader" in their name. Loader files are compiled and loaded like any ordinary Logtalk source file. For an example loader file named <code>loader.lgt</code> we would type:
</p>
<pre>
| ?- logtalk_load(loader).
</pre>
<p>
Usually these files contain a call to the Logtalk built-in predicates <a title="Consult reference manual" href="../refman/builtins/logtalk_load1.html"><code>logtalk_load/1</code></a> or <a title="Consult reference manual" href="../refman/builtins/logtalk_load2.html"><code>logtalk_load/2</code></a>, wrapped inside an <code>initialization/1</code> directive. For instance, if your code is split in three Logtalk source files named <code>source1.lgt</code>, <code>source2.lgt</code>, and <code>source3.lgt</code>, then the contents of your loader file could be:
</p>
<pre>
:- initialization(
logtalk_load([
source1,
source2,
source3])).
</pre>
<p>
Another example of directives that are often used in a loader file would be <code>op/3</code> directives declaring global operators needed by your application.
</p>
<p>
To take the best advantage of loader files, assert a clause to the dynamic predicate <code>logtalk_library_path/2</code> for the directory containing your source files, as explained in the next section.
</p>
<h3>Libraries of source files<a name="libraries"></a></h3>
<p>
Logtalk defines a <em>library</em> simply as a directory containg source files. Library locations can be specified by asserting clauses to the dynamic predicate <code>logtalk_library_path/2</code>. For example:
</p>
<pre>
| ?- assertz(logtalk_library_path(shapes, '$LOGTALKHOME/examples/shapes/')).
</pre>
<p>
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 <code>loader.lgt</code> file, contained in a library named <code>shapes</code>, we just need to type:
</p>
<pre>
| ?- logtalk_load(shapes(loader)).
</pre>
<p>
The best way to take advantage of this feature is to load at startup a source file containing an <code>initialization/1</code> directive which asserts all the <code>logtalk_library_path/2</code> clauses needed for all available libraries. This allows us to load library source files or entire libraries without worrying about libraries paths, improving code portability.
</p>
<p>
Unfortunately, a few Prolog compilers do not support the <code>&lt;library&gt;(&lt;entity&gt;)</code> notation. In this case, you will need to set the working directory to be the one that contains the entity file in order to load it.
</p>
<h3>Portable programs<a name="portability"></a></h3>
<p>
Logtalk is compatible with almost all modern Prolog compilers. However, this does not necessarily imply that your Logtalk programs will have the same level of portability. If possible, you should only use in your programs Logtalk built-in predicates and ISO Prolog defined built-in predicates. If you need to use built-in predicates that may not be available in other Prolog compilers, you should try to encapsulate the non-portable code in a minimum of objects and provide a portable <strong>interface</strong> 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 defined built-in predicates by using the <code>portability/1</code> compiler flag.
</p>
<h3>Avoiding common errors<a name="errors"></a></h3>
<p>
Try to write objects and protocol documentation <strong>before</strong> writing any other code; if you are having trouble documenting a predicate perhaps we need to go back to the design stage.
</p>
<p>
Try to avoid lengthy hierarchies. Besides performance penalties, composition is often a better choice over inheritance for defining new objects (Logtalk supports component-based programming through the use of categories). In addition, prototype-based hierarchies are conceptually simpler and more efficient than class-based hierarchies.
</p>
<p>
Dynamic predicates or dynamic entities are sometimes needed, but we should always try to minimize the use of non-logical features like destructive assignment (asserts and retracts).
</p>
<p>
Since each Logtalk entity is independently compiled, if an object inherits a dynamic or a metapredicate predicate, then we must repeat the respective directives in order to ensure a correct compilation.
</p>
<p>
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 carefully checked for calling mode errors.
</p>
<p>
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-ins behave as defined in the ISO standard regarding error conditions. In particular, if your Prolog compiler does not support a <code>read_term/3</code> built-in predicate compliant with the ISO Prolog Standard definition, then the current version of the Logtalk preprocessor will not be able to detect misspell variables in your source code.
</p>
<h2>Logtalk scope<a name="scope"></a></h2>
<p>
Logtalk, as an object-oriented extension to Prolog, shares with it the same preferred areas of application but also extends them with those areas where object-oriented features provide an advantage compared to plain Prolog. Among these areas we have:
</p>
<dl>
<dt><strong>Object-oriented programming teaching and researching</strong></dt>
<dd>Logtalk smooth learning curve, combined with support for both prototype and class-based programming, protocols, components via category-based composition, and other advanced object-oriented features allow a smooth introduction to object-oriented programming to people with a background in Prolog programming. The distribution of Logtalk source code using an open-source license provides a framework for people to learn and then modify to try out new ideas on object-oriented programming research.</dd>
</dl>
<dl>
<dt><strong>Structured knowledge representations and knowledge-based systems</strong></dt>
<dd>Logtalk objects, coupled with event-driven programming features, enable easy implementation of frame-like systems and similar structured knowledge representations.</dd>
</dl>
<dl>
<dt><strong>Blackboard systems, agent-based systems and systems with complex object relationships</strong></dt>
<dd>Logtalk support for event-driven programming can provide a basis for the dynamic and reactive nature of blackboard type applications.</dd>
</dl>
<dl>
<dt><strong>Highly portable applications</strong></dt>
<dd>Logtalk is compatible with almost any modern Prolog compiler. Used as a way to provide Prolog with namespaces, it avoids the porting problems of most Prolog module systems. Platform, operating system, or compiler specific code can be isolated from the rest of the code by encapsulating it in objects with well defined interfaces.</dd>
</dl>
<dl>
<dt><strong>Alternative to a Prolog module system</strong></dt>
<dd>Logtalk can be used as an alternative to a Prolog compiler module system. Any Prolog application that use modules can be converted to a Logtalk application, improving portability across Prolog compilers and taking advantage of the stronger reuse framework provided by Logtalk object-oriented features.</dd>
</dl>
<dl>
<dt><strong>Integration with other programming languages</strong></dt>
<dd>Logtalk support for most key object-oriented features helps users integrating Prolog with object-oriented languages like C++, Java, or Smalltalk by providing an high-level mapping between the two languages.</dd>
</dl>
<div class="navbottom">
<a href="running.html">previous</a> | <a href="../glossary.html">glossary</a> | <a href="index.html">next</a>
</div>
<div class="copyright">
Copyright &copy; <a href="mailto:pmoura@logtalk.org">Paulo Moura</a> &mdash; <a href="http://www.logtalk.org">Logtalk.org</a>
</div>
<div class="footer">
<p><span class="bleft"><a href="http://validator.w3.org/check/referer">XHTML</a> + <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a></span><span class="bright">Last updated on: February 6, 2005</span></p>
</div>
</body>
</html>