I have released a new version of Seed7: seed7_05_20070823.tgz
In the Seed7 programming language new statements and operators
can be declared easily. Types are first class objects and therefore
templates/generics need no special syntax. Object orientation is
used when it brings advantages and not in places when other
solutions are more obvious.
Seed7 is covered by the GPL (and LGPL for the Seed7 runtime library).
Changelog:
- The compiler was improved to support nested exceptions.
- The planets.sd7 example program was improved to contain a
panorama with stars and planets.
- An include file (stars.s7i) which contains the names and
coordinates of stars was added.
- The intParse function was improved to accepts a plus (+) sign.
- The memory management of the socRecv function was improved.
- Some exception tests were added to chkexc.sd7
- A test for check_atan2 was added to the chkflt.sd7 program.
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.
Well, why is that a boon? As long as you can add new functionality by
defining functions, what does it matter?
> Types are first class objects and therefore
> templates/generics need no special syntax.
Does this mean the built-in types can be extended with methods? The
inability to do this in Java is biting me right now!
> Object orientation is
> used when it brings advantages and not in places when other
> solutions are more obvious.
class-based or prototype-based? I'm all for prototype-based.
oh looks class-based.
>
> Seed7 Homepage: http://seed7.sourceforge.net
The header on the webpage is creative.
> Seed7 - The extensible programming language: User defined statements
> and operators, abstract data types, templates without special
> syntax, OO with interfaces and multiple dispatch.
What is the underscore after the numbers for:
for number range 1_ to 20_ do
writeln(1_/number digits 60);
end for;
We're basically talking about metaprogramming here. This is what Lisp
macros are for, so this is like yet another discussion about the utility
of Lisp macros, except that, this time, it's not about Lisp and macros,
but about Seed7 and its metaprogramming capabilities.
Metaprogramming matters, because it allows you to abstract more things.
As you know, functions are an abstraction, and, as such, can make your
code less repetitive, smaller, and easier to understand. However, there
are some cases which can not be abstracted by functions.
Since the specifics of how far functions can take you depend on the
language, and I don't actually know Seed7, I can't provide any real
examples, but some things that metaprogramming is typically used for
are:
1. Control over evaluation. Arguments you pass to functions are
typically evaluated exactly once (in languages with lazy evaluation,
this would be once or never). Using metaprogramming, you can implement
your own control structures, which can evaluate their arguments any
number of times.
I believe many Seed7 control structures are actually defined in
libraries using metaprogramming, rather than baked into the language.
This is not really an issue in some languages. For example, in
Smalltalk, there are no control structures. Things like ifTrue take a
block as argument, which any function can do. Since the code in blocks
is not evaluated unless this is done explicitly, you get evaluation
control without metaprogramming.
2. Eliminating repetitive code. Have you ever written code that
consisted of consecutive lines that were almost identical? Perhaps
something like (after fetching a row from the database):
someObject.someProperty = row["someProperty"];
someObject.someOtherProperty = row["someOtherProperty"];
..
Wouldn't it be nice if you could condense this to, say,
setPropertiesFromRow(someObject, row,
someProperty, someOtherProperty, ...);
?
With metaprogramming, you can do that. What you do is basically write a
program that generates the code you need to write. The compiler then
executes this program for you and, presto, you now have the code you
needed, but with less typing on your behalf.
At any point where your code becomes repetitive, think abstraction. If
your abstraction cannot be done by functions, it's a job for
metaprogramming.
Regards,
Bob
--
May the source be with you!
Infix operators have a long tradition. For example in the area of
mathematic, physic and other areas. The possibility to declare
operators with priority and assoziativity allows you to use such
traditional notations (to some degree).
> > Types are first class objects and therefore
> > templates/generics need no special syntax.
>
> Does this mean the built-in types can be extended with methods? The
> inability to do this in Java is biting me right now!
Yes, in Seed7 you can extend any type with methods.
> > Object orientation is
> > used when it brings advantages and not in places when other
> > solutions are more obvious.
>
> class-based or prototype-based? I'm all for prototype-based.
> oh looks class-based.
Seed7 uses a multiple dispatch system
(see: http://seed7.sourceforge.net/faq.htm#multiple_dispatch).
Therefore methods are not connected to one class.
> > Seed7 Homepage: http://seed7.sourceforge.net
>
> The header on the webpage is creative.
Thank you
> > Seed7 - The extensible programming language: User defined statements
> > and operators, abstract data types, templates without special
> > syntax, OO with interfaces and multiple dispatch.
>
> What is the underscore after the numbers for:
> for number range 1_ to 20_ do
> writeln(1_/number digits 60);
> end for;
Integer literals without underscore have the type 'integer'.
Integer literals with underscore have the type 'bigInteger'.
Greetings Thomas Mertes
Seed7 Homepage: http://seed7.sourceforge.net
The metaprogramming capabilities of Seed7 are not necessary to define
new operators. The infix operators of Seed7 are just functions which
use a different syntax. A Seed7 operator is not a macro which
generates
a function call. Instead the Seed7 'syntax' definition specifies
keywords, priority and assoziativity of an expression. The semantic
definition of the operator is like an function declaration, but
uses the defined operator syntax. There is no function call equivalent
to an operator as it would be in a macro solution. For example:
$ syntax expr: .(). + .() is -> 7;
This defines the syntax of the infix + operator.
The semantic of the infix + for complex numbers is defined as:
const func complex: (in complex: num1) + (in complex: num2) is func
result
var complex: result is complex.value;
begin
result.re := num1.re + num2.re;
result.im := num1.im + num2.im;
end func;
A call of this + operator would be:
a + b
but there is no function call equivalent like:
+(a, b)
So there is no macro like conversion from operator notation
to function notation.
> Metaprogramming matters, because it allows you to abstract more things.
> As you know, functions are an abstraction, and, as such, can make your
> code less repetitive, smaller, and easier to understand. However, there
> are some cases which can not be abstracted by functions.
>
> Since the specifics of how far functions can take you depend on the
> language, and I don't actually know Seed7, I can't provide any real
> examples, but some things that metaprogramming is typically used for
> are:
>
> 1. Control over evaluation. Arguments you pass to functions are
> typically evaluated exactly once (in languages with lazy evaluation,
> this would be once or never). Using metaprogramming, you can implement
> your own control structures, which can evaluate their arguments any
> number of times.
The Seed7 functions can have parameters which are not evaluated when
the function is called. For example:
$ syntax expr: .myIf.().then.().end.if is -> 25;
const proc: myIf (in boolean: cond) then
(in proc: stat)
end if is func
begin
case cond of
when {TRUE}: stat;
end case;
end func;
The 'stat' parameter is not evaluatend when 'myIf' is called,
because it uses a parameter with the type 'proc'. In the function
body the 'stat' parameter might be evaluated depending on 'cond'.
The 'cond' parameter is evaluated exactly once when 'myIf' is called.
In the following example 'cond' must be handled different:
$ syntax expr: .myWhile.().do.().end.while is -> 25;
const proc: myWhile (in func boolean: cond) do
(in proc: stat)
end while is func
begin
if cond then
stat;
myWhile cond do
stat;
end while;
end if;
end func;
This 'cond' parameter is not evaluated when 'myWhile' is called.
Instead it could be evaluated zero or multiple times in the function
body.
You see that in Seed7 you can decide between parameters that are
evaluated exactly once and parameters with lazy evaluation.
This decision is done explizit using the type of a parameter.
> I believe many Seed7 control structures are actually defined in
> libraries using metaprogramming, rather than baked into the language.
As you have seen above metaprogramming is not necessary to define
statements. Instead syntax statements and types for lazy evaluation
are used.
An example using metaprogramming would be the following 'for'
statement:
const proc: FOR_DECLS (in type: aType) is func
begin
const proc: for (inout aType: variable) range
(in aType: low) to (in aType: high) do
(in proc: statements)
end for is func
begin
variable := low;
if variable <= high then
statements;
while variable < high do
incr(variable);
statements;
end while;
end if;
end func;
end func;
FOR_DECLS(char);
FOR_DECLS(boolean);
The FOR_DECLS function provides a template of how to declare a 'for'
loop. The last two lines of the example define 'for' loops for the
types 'char' and 'boolean'.
Greetings Thomas Mertes
Seed7 Homepage: http://seed7.sourceforge.net
>
> 2. Eliminating repetitive code. Have you ever written code that
> consisted of consecutive lines that were almost identical? Perhaps
> something like (after fetching a row from the database):
>
> someObject.someProperty = row["someProperty"];
> someObject.someOtherProperty = row["someOtherProperty"];
> ..
>
> Wouldn't it be nice if you could condense this to, say,
> setPropertiesFromRow(someObject, row,
> someProperty, someOtherProperty, ...);
I think you hit the nail on the head here. The key is that the
_compiler_ does it at compile time instead of the CPU doing it at
runtime.
And yes, sometimes I do feel handcuffed by obvious repetition that I
can do nothing about.