On 30 Jun., 17:43, Juha Nieminen <nos...@thanks.invalid> wrote:
> Adem24 wrote:
> > 1) There is no goto statement.
> > Hidden goto's like break- and continue-statements are also omitted.
>
> > 2) There is no return statement.
> > Instead a result variable can be declared to which the result of a function can be assigned.
>
> Is the goal of this language to make the life of programmers as hard
> as possible? Something like this becomes difficult to implement:
>
> // Find the first value in 'data' which meets the requirements imposed
> // by the parameter:
> Type1 foo(Type2 value)
> {
> for(size_t i = 0; i < data.size(); ++i)
> for(size_t j = 0; j < data[i].size(); ++j)
> for(size_t k = 0; k < data[i][j].size(); ++k)
> if(meetsRequirements(data[i][j][k], value)
> return data[i][j][k];
>
> }
Your function returns garbage when nothing meets the requirements.
Your solution may be elegant, but it is wrong (I know that it can
be fixed easily). Some people would even argue that with structured
programming such bugs would not happen.
Besides that, I got your point.
Before going to the details let me explain the advantage when every
statement has exactly one entry and one exit (this is a side effect
of structured programming without any form of goto's):
If you want to add code that should be executed when the function
is left (e.g. some trace statement) you can just add it at the end
of the function. The only reason that your trace code is skipped is
when an exception is raised and no exception handler inside the
function catches it. If there are no exceptions you know that the
flow of control is always stuctured. If you jump around in your
code with gotos and returns you don't have this guarantee.
A stuctured solution to your example could use a boolean flag which
is changed when the data is found. It can be argued that this is
slower but todays compiler optimisations should not be
unerestimated. A C version of this structured function would be:
// Find the first value in 'data' which meets the requirements
// imposed by the parameter:
Type1 foo (Type2 value)
{
int search = 1;
Type1 result = Type1default;
for (size_t i = 0; i < data.size() & search; ++i) {
for (size_t j = 0; j < data[i].size() & search; ++j) {
for (size_t k = 0; k < data[i][j].size() & search; ++k) {
if (meetsRequirements(data[i][j][k], value) {
result = data[i][j][k];
search = 0;
}
}
}
}
return result;
}
As you can see, I prefer to use curly braces even when they are not
necessary. This use of curly braces allowes that statements
belonging to 'while', 'do', 'for' and 'if' statements can always be
added or removed without unintentionally changing the logic. The
use of a result variable makes clear which function holds the
result of the function. Since C needs a return statement I just put
it in front of the closing curly brace. IMHO a good compiler can
produce code which is as fast as your version.
In a language which has no C for loops like Seed7 the function
would look as follows:
const func Type1: foo (in Type2: aValue) is func
result
var Type1: result is Type1.value;
local
var integer: i is 1;
var integer: j is 1;
var integer: k is 1;
var boolean: search is TRUE;
begin
while i <= maxIdx(data) and search do
while j <= maxIdx(data[i]) and search do
while k < maxIdx(data[i][j]) and search do
if meetsRequirements(data[i][j][k], aValue) then
result := data[i][j][k];
search := FALSE;
end if;
incr(k);
end while;
incr(j);
end while;
incr(i);
end while;
end func;
I know that this solution is not as elegant.
Maybe I should introduce an advanced version of the 'for' statement
like:
for i range minIdx(data) range maxIdx(data) andWhile search do
What do you think?
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, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.