seed7-users Mailing List for Seed7 (Page 11)
Interpreter and compiler for the Seed7 programming language.
Brought to you by:
thomas_mertes
You can subscribe to this list here.
| 2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2008 |
Jan
|
Feb
(9) |
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
(4) |
Aug
|
Sep
(4) |
Oct
(4) |
Nov
|
Dec
(1) |
| 2011 |
Jan
(2) |
Feb
|
Mar
(8) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2012 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
|
Jun
|
Jul
(2) |
Aug
(6) |
Sep
(7) |
Oct
(3) |
Nov
(10) |
Dec
(4) |
| 2013 |
Jan
(2) |
Feb
|
Mar
(2) |
Apr
|
May
(1) |
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
(5) |
Nov
|
Dec
(1) |
| 2014 |
Jan
(1) |
Feb
|
Mar
|
Apr
(1) |
May
(6) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(4) |
Nov
(1) |
Dec
(1) |
| 2015 |
Jan
(2) |
Feb
(2) |
Mar
(2) |
Apr
|
May
(3) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(3) |
Dec
|
| 2016 |
Jan
|
Feb
(3) |
Mar
(2) |
Apr
|
May
(3) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2017 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2019 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(2) |
Jun
|
Jul
|
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
|
| 2020 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(3) |
Dec
(3) |
| 2021 |
Jan
(2) |
Feb
(6) |
Mar
(1) |
Apr
(1) |
May
(1) |
Jun
(2) |
Jul
|
Aug
(1) |
Sep
(12) |
Oct
(4) |
Nov
(17) |
Dec
(3) |
| 2022 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
(2) |
May
|
Jun
(17) |
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2023 |
Jan
|
Feb
(1) |
Mar
(4) |
Apr
|
May
|
Jun
(3) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
(1) |
Nov
|
Dec
|
| 2024 |
Jan
|
Feb
(5) |
Mar
(7) |
Apr
|
May
|
Jun
|
Jul
(4) |
Aug
(12) |
Sep
|
Oct
|
Nov
|
Dec
(2) |
| 2025 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(11) |
Nov
(5) |
Dec
|
|
From: Thomas M. <tho...@gm...> - 2008-02-10 15:03:56
|
Hello,
I am writing a chapter about object orientation.
It would be nice to get some feedback about it
before the final release. Here is it:
7. OBJECT ORIENTATION
=====================
The object orientation of Seed7 is based on terms like
interface and implementation. An interface defines which
methods are supported while the implementation describes
how this is done. Several classes with different method
implementations share the same interface. This view is not
something new. When you write to a file (in C under UNIX)
you use the same interface (higher level printf or lower
level write) for harddisk files, console output and printer
output. The implementation does totally different things
for this files. UNIX uses the "everything is a file"
philosopy for ages (even network communication uses the
file interface (see sockets)).
7.1 Interface and implementation
Seed7 uses interface types and implementation types.
Objects declared with an interface type refer to a value
which has an implementation type. The interface type of
an object can always be determined at compile-time. Several
implementation types can belong to one interface type (they
implement the interface type). E.g.: The types 'NULL_FILE',
'external_file' and 'socket' implement the 'file' interface.
An interface object can only refer to a value with an
implementation type that implements the interface. E.g.:
A 'shape' variable cannot refer to a 'socket'.
A new interface type is declared with:
const type: shape is new interface;
Interface (DYNAMIC) functions describe what can be done
with objects of an interface type. An interface function
for a 'shape' could be:
const proc: draw (in shape param, inout window param) is DYNAMIC;
Now we know that it is possible to 'draw' a 'shape' to a
'window'. How this drawing is done is described in the
implementation type. An implementation type for 'shape' is:
const type: circle is new struct
var integer: radius is 0;
end struct;
The fact that the type 'circle' is an implementation type of
'shape' is described with:
type_implements_interface(circle, shape);
The function which implements 'draw' for 'circle's is:
const proc: draw (in circle: aCircle, inout window: aWindow) is
func
begin
circle(aWindow.win, aWindow.currX, aWindow.currY,
aCircle.radius, aWindow.foreground);
end func;
In the classic OOP philosopy a message is sent to an object.
In the method the receiving object is referred with 'self' or
'this'. The other parameters use the same mechanisms as in
procedural programming languages (value or reference parameter).
Seed7 uses a different approach: All parameters get a user
defined name. In the above example the name 'aCircle' was used
for the 'self'/'this' parameter.
A function to create new circle objects can also be helpful:
const func circle: circle (in integer: radius) is func
result
var circle: result is circle.value;
begin
result.radius := radius;
end func;
Now we can draw a 'circle' object with:
draw(circle(50), aWindow);
Although there is a 'draw' function declared for 'circle' it
is not called directly. Instead the 'draw' interface function
for 'shape' is called. When the program is analyzed (in the
interpreter or compiler) interface functions take precedence
over normal functions when both are to be considered.
The interface function for 'shape' decides which implementation
function has to be called. This decision process is called
dynamic dispatch. In the above example the overhead of the
dynamic dispatch seems to be unnecessary, but in general it
is the way object orientation works also in other languages.
7.2 Dynamic dispatch
When the implementation types have different implementations
of the same function (method) a dynamic dispatch is necessary.
The type of the value, refered by an interface object, is not
known at compile-time. In this case the program must decide at
runtime which implementation of the function should be invoked.
This decision is based on the type of the value of an object.
A dynamic dispatch is described with a dynamic (or interface)
function.
To demonstrate the dynamic dispatch we define the type 'line'
which also implements a 'shape':
const type: line is new struct
var integer: xLen is 0.0;
var integer: yLen is 0.0;
end func;
type_implements_interface(line, shape);
const proc: draw (in line: aLine, in window: aWindow) is func
begin
line(aWindow.win, aWindow.currX, aWindow.currY,
aLine.xLen, aLine.yLen, aWindow.foreground);
end func;
const func line: line (in integer: xLen, in integer: yLen) is func
result
var line: result is line.value;
begin
result.xLen := xLen;
result.yLen := yLen;
end func;
In addition we define a normal (not DYNAMIC) function
which draws 'shape's to the 'currWindow':
const proc: draw (in shape: aShape) is func
begin
draw(aShape, currWindow);
end func;
In the above example the call of the (DYNAMIC) interface
function is 'draw(aShape, currWindow)'. For this call the
dynamic dispatch works as follows:
- For all parameters which have an interface type the
parameter is replaced with its value. In this case the
parameter 'aShape' is replaced by a value of type
'circle' or 'line'.
- The same logic as in the analyze part of the compiler
is used to find the matching function. This time normal
functions take precedence over interface functions.
- When a matching function is found it is called.
This process describes the principal logic of the dynamic
dispatch. In practice it is not necessary to execute the
analyze part of the compiler during the runtime. It is
possible to simplify this process with tables and function
pointers.
7.3 Inheritance
When a new 'struct' type is defined it is possible to
inherit from an existing 'struct' type. E.g.:
const type: external_file is sub NULL_FILE struct
var PRIMITIVE_FILE: ext_file is PRIMITIVE_NULL_FILE;
var string: name is "";
end struct;
That way the type 'external_file' inherits the fields and
methods of 'NULL_FILE'. In most situations it makes sense
when the implementation types inherit from a basic
implementation type such as 'NULL_FILE'.
In other OO languages the distinction between interface type
and basic implementation type is not done. Such languages
either use a dynamic dispatch for every method call (as Java
does) or need a keyword to request a dynamic dispatch (as C++
does with the 'virtual' keyword).
A new interface type can also inherit from an existing
interface type:
const type: shape is sub object interface;
Although inheritance is a very powerful feature it should
be used with care. In many situations it makes more sense
that a new type has an element of another type (so called
has-a relation) instead of inheriting from that type (so
called is-a relation).
7.4 Multiple dispatch
The Seed7 object system allows multiple dispatch (not to
be confused with multiple inheritance). The methods are
not assigned to one type (class). The decision which
function (method) is called at runtime is done based upon
the types of several arguments. The classic object
orientation is a special case where a method is connected
to one class and the dispatch decision is done based on
the type of the 'self' or 'this' parameter.
The classic object orientation is a single dispatch system.
In the following example the type 'Number' is introduced
which is capable to unify numerical types. The type
'Number' is an interface type which defines
the inferface function for the '+' operation:
const type: Number is sub object interface;
const func Number: (in Number param) + (in Number param) is
DYNAMIC;
The interface type 'Number' can represent an 'Integer' or a 'Float':
const type: Integer is new struct
var integer: val is 0;
end struct;
type_implements_interface(Integer, Number);
const type: Float is new struct
var float: val is 0.0;
end struct;
type_implements_interface(Float, Number);
The declarations of the converting '+' operators are:
const func Float: (in Integer: a) + (in Float: b) is func
result
var Float: result is Float.value;
begin
result.val := flt(a.val) + b.val;
end func;
const func Float: (in Float: a) + (in Integer: b) is func
result
var Float: result is Float.value;
begin
result.val := a.val + flt(b.val);
end func;
The declarations of the normal '+' operators (which do not convert)
are:
const func Integer: (in Integer: a) + (in Integer: b) is func
result
var Integer: result is Integer.value;
begin
result.val := a.val + b.val;
end func;
const func Float: (in Float: a) + (in Float: b) is func
result
var Float: result is Float.value;
begin
result.val := a.val + b.val;
end func;
The type 'Number' can be extended to support other
operators and there can be also implementations using
'complex', 'bigInteger', 'bigRational', etc. . That way
'Number' can be used as universal type for math
calculation. Further extending can lead to an universal
type. Such an universal type is loved by proponents of
dynamic typed languages, but there are also good reasons
to have destinct types for different purposes.
================================
Thanks in advance for your effort.
Greetings Thomas Mertes
Seed7 Homepage: http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch.
--
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger
|
|
From: Thomas M. <tho...@gm...> - 2007-09-09 19:55:32
|
Welcome to the Seed7 discussion list This list is for Seed7 user and developer discussions. Feel free to ask any questions about Seed7. Greetings Thomas Mertes Seed7 Homepage: http://seed7.sourceforge.net Seed7 - The extensible programming language: User defined statements and operators, abstract data types, templates without special syntax, OO with interfaces and multiple dispatch. -- Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kanns mit allen: http://www.gmx.net/de/go/multimessenger |