Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > by-pkgid > 2fc07611b08d4a735fd34d5eb60d8e16 > files > 2057

ciao-1.10p8-3mdv2010.0.i586.rpm

<HTML>
<HEAD>
<!-- Created by texi2html 1.56k + clip patches and <A href="http://www.clip.dia.fi.upm.es/Software">lpdoc</A> from ciao.texi on 28 January 2007 -->

<LINK rel="stylesheet" href="ciao.css" type="text/css">
<TITLE>The Ciao Prolog System               - Object oriented programming</TITLE>
</HEAD>
<BODY> 
Go to the <A HREF="ciao_1.html">first</A>, <A HREF="ciao_113.html">previous</A>, <A HREF="ciao_115.html">next</A>, <A HREF="ciao_241.html">last</A> section, <A HREF="ciao_toc.html">table of contents</A>.
<P><HR><P>


<H1><A NAME="SEC473" HREF="ciao_toc.html#TOC473">Object oriented programming</A></H1>

<P>
<STRONG>Author(s):</STRONG> Angel Fernandez Pineda.


<P>
<STRONG>Version:</STRONG> 1.10#7 (2006/4/26, 19:22:13 CEST)


<P>
<STRONG>Version of last change:</STRONG> 1.3#63 (1999/9/29, 19:54:17 MEST)


<P>
O'Ciao is a set of libraries which allows object-oriented programming in Ciao Prolog. It extends the Ciao Prolog module system by introducing two new concepts: 



<UL>
<LI>Inheritance.

<LI>Instantiation.

</UL>

<P>
<A NAME="IDX5519"></A>
<A NAME="IDX5520"></A>
<EM>Polymorphism</EM> is the third fundamental concept provided by object oriented programming. This concept is not mentioned here since <STRONG>traditional PROLOG systems are polymorphic by nature</STRONG>. 


<P>
Classes are declared in the same way as modules. However, they may be enriched with inheritance declarations and other object-oriented constructs. For an overview of the fundamentals of O'Ciao, see <A HREF="http://www.clip.dia.fi.upm.es/~clip/papers/ociao-tr.ps.gz">http://www.clip.dia.fi.upm.es/~clip/papers/ociao-tr.ps.gz</A>. However, we will introduce the concepts in a tutorial way via examples. 



<UL>
<LI><A HREF="ciao_114.html#SEC474">Early examples</A>
<LI><A HREF="ciao_114.html#SEC475">Recommendations on when to use objects</A>
<LI><A HREF="ciao_114.html#SEC476">Limitations on object usage</A>
</UL>



<H2><A NAME="SEC474" HREF="ciao_toc.html#TOC474">Early examples</A></H2>

<P>
The following one is a very simple example which declares a class -- a simple stack. Note that if you replace <EM>class/1</EM> declaration with a <EM>module/1</EM> declaration, it will compile correctly, and can be used as a normal Prolog module. 



<PRE>
%%----------------------------------------------%%
%% A class for stacks.                          %%
%%----------------------------------------------%%

%% Class declaration: the current source defines a class.
:- class(stack,[],[]).

% State declaration: storage/1 is an attribute.
:- dynamic storage/1.

% Interface declaration: the following predicates will
% be available at run-time.
:- export(push/1).
:- export(pop/1).
:- export(top/1).
:- export(is_empty/0).

% Methods

push(Item) :-
        nonvar(Item), 
        asserta_fact(storage(Item)).

pop(Item) :-
        var(Item),
        retract_fact(storage(Item)).

top(Top) :-
        storage(Top), !.

is_empty :-
        storage(_), !, fail.
is_empty.

</PRE>

<P>
If we load this code at the Ciao toplevel shell: 



<PRE>
        ?- use_package(objects).

        yes
        ?- use_class(library('class/examples/stack')).

        yes
        ?-
</PRE>

<P>
we can create two stack <EM>instances</EM> : 



<PRE>
        ?- St1 new stack,St2 new stack.

        St1 = stack('9254074093385163'),
        St2 = stack('9254074091') ? ,
</PRE>

<P>
and then, we can operate on them separately: 



<PRE>
        1 ?- St1:push(8),St2:push(9).

        St1 = stack('9254074093385163'),
        St2 = stack('9254074091') ? 

        yes
        1 ?- St1:top(I),St2:top(K).

        I = 8,
        K = 9,
        St1 = stack('9254074093385163'),
        St2 = stack('9254074091') ? 

        yes
        1 ?-
</PRE>

<P>
The interesting point is that there are two stacks. If the previous example had been a normal module, we would have a stack , but <STRONG>only one</STRONG> stack. 


<P>
The next example introduces the concepts of <EM>inheritable</EM> predicate, <EM>constructor</EM>, <EM>destructor</EM> and <EM>virtual method</EM>. Refer to the following sections for further explanation. 



<PRE>
%%----------------------------------------------%%
%% A generic class for item storage.            %%
%%----------------------------------------------%%
:- class(generic).

% Public interface declaration:
:- export([set/1,get/1,callme/0]).

% An attribute
:- data datum/1.

% Inheritance declaration: datum/1 will be available to 
% descendant classes (if any).
:- inheritable(datum/1).

% Attribute initialization: attributes are easily initialized
% by writing clauses for them.
datum(none).

% Methods

set(X) :-
        type_check(X),
        set_fact(datum(X)).

get(X) :-
        datum(X).

callme :-
        a_virtual(IMPL),
        display(IMPL),
        display(' implementation of a_virtual/0 '),
        nl.

% Constructor: in this case, every time an instance
% of this class is created, it will display a message.
generic :-
        display(' generic class constructor '),
        nl.

% Destructor: analogous to the previous constructor,
% it will display a message every time an instance
% of this class is eliminated.
destructor :-
        display(' generic class destructor '),
        nl.

% Predicates:
% cannot be called as messages (X:method)

% Virtual declaration: tells the system to use the most
% descendant implementation of a_virtual/1 when calling
% it from inside this code (see callme/0).
% If there is no descendant implementation for it, 
% the one defined bellow will be used.
:- virtual a_virtual/1.

a_virtual(generic).

:- virtual type_check/1.

type_check(X) :-
        nonvar(X).

</PRE>

<P>
And the following example, is an extension of previous class. This is performed by establishing an inheritance relationship: 



<PRE>
%%----------------------------------------------%%
%% This class provides additional functionality %%
%% to the "generic" class.                      %%
%%----------------------------------------------%%
:- class(specific).

% Establish an inheritance relationship with class "generic".
:- inherit_class(library('class/examples/generic')).

% Override inherited datum/1.
% datum/1 is said to be overriden because there are both an
% inherited definition (from class "generic") and a local one,
% which overrides the one inherited.
:- data datum/1. 
:- inheritable datum/1.

% Extend the public interface inherited from "generic".
% note that set/1 and a_virtual/0 are also overriden. 
% undo/0 is a new functionality added.
:- export([set/1,undo/0]).

% Methods

set(Value) :-
        inherited datum(OldValue),
        !,
        inherited set(Value),
        asserta_fact(datum(OldValue)).
set(Value) :-
        inherited set(Value).

undo :-
        retract_fact(datum(Last)), !,
        asserta_fact(inherited(datum(Last))).
undo :-
        retractall_fact(inherited(datum(_))).

% Constructor
specific :-
        generic,
        retractall_fact(inherited(datum(_))),
        display(' specific class constructor '),
        nl.

% Destructor
destructor :-
        display(' specific class destructor '),
        nl.

% Predicates

% New implementation of a_virtual/1. 
% Since this predicate was declared virtual, the
% implementation below will be called from the inherited 
% method callme/0 instead of the version defined at "generic".
a_virtual(specific).

</PRE>

<P>
<STRONG>Additional examples</STRONG> may be found on the <EM>library/class/examples</EM> directory relative to your Ciao Prolog instalation. 




<H2><A NAME="SEC475" HREF="ciao_toc.html#TOC475">Recommendations on when to use objects</A></H2>

<P>
We would like to give some advice in the use of object oriented programming, in conjunction with the declarative paradigm. 


<P>
You should reconsider using O'Ciao in the following cases: 



<UL>

<LI>The pretended "objects" have no state,i.e., no data or dynamic predicates. In this case, a normal module will suffice.

<LI>There is state, but there will be only one instance of a pretended class. Again, a module suffices.

<LI>The "objects" are data structures (list,trees,etc) already supported by Prolog. However, it does make sense to model, using objects, data structures whose change implies a side-effect such as drawing a particular window on the screen.

</UL>

<P>
We recommend the usage of O'Ciao in the following cases: 



<UL>

<LI>You feel you will need to have several copies of a "module".

<LI>Local copies of a module are needed instead of a global module beeing modified by several ones.

<LI>The "classes" are a representation of external entities to Prolog. For example: the X-Window system.

<LI>There is state or code outside the Prolog system which needs to be manipulated. For example: interfaces to Java or Tcl/Tk code.

<LI>You are not familiar with Prolog, but you know about object oriented programming. O'Ciao may be used as a learning tool to introduce yourself on the declarative programming paradigm.

</UL>



<H2><A NAME="SEC476" HREF="ciao_toc.html#TOC476">Limitations on object usage</A></H2>

<P>
O'Ciao run-time speed is limited by the usage of meta-programming structures, for instance: <CODE>X = (Object:mymethod(25)), call(X)</CODE>. O'Ciao will optimize static manipulation of objects (those that can be determined at compile time). 


<P><HR><P>
Go to the <A HREF="ciao_1.html">first</A>, <A HREF="ciao_113.html">previous</A>, <A HREF="ciao_115.html">next</A>, <A HREF="ciao_241.html">last</A> section, <A HREF="ciao_toc.html">table of contents</A>.
</BODY>
</HTML>