Board index » delphi » Re: Maybe something to vote for...

Re: Maybe something to vote for...


2006-06-28 01:31:00 AM
delphi129
Hi!
Quote
>>But you could do that! Long as you know in advance its going to return
>>a boolean and an integer, define a record
>
>Most importantly, that works only for simple types. And
>not for objects or pointers.

?? I have many functions that return objects. The objects are often
complex, containing other objects.
I replied to Liz :) The extended syntax allows course allows this,
but records dont.
It is by convention that functions should normally not return
objects that they created. Here is how it works for objects:
function ComputeABC(p1: t1; p2: t2): (a,c: TArray);
begin
...
a.Copy(array);
c.Copy(arrayc);
end;
And you call it like this:
(YourAObject, YourCObject) := ComputeABC(p1,p2);
Regards!
Atmapuri
 
 

Re: Maybe something to vote for...

Hi!
Quote
I'm not too fond of this syntax, as it neither makes it obvious that
you're passing references or parameters to the function (references that
could be passed to another function, etc.), nor does it ensures that the
function's results can be assumed to be a *result*.
You mean exactly the same as this:
ComputeABC(p1,p2, a, b, c);
procedure call which requires a,b,c objects
to be created before you pass them to the function
and returns a,b,c filled with your data?
Which is what we do now? :)
And looking at it you have no idea if any of the parameters
are suppose to be input or input, by var,
ref, objects or whatever.
The ambiguoty here is that you assume that the result
of the function should be strictly new variable value,
and I allow for the object contents to hold the result.
Quote
With your syntax, you blur the line between result and reference
parameters, so when I see

(object1, object2) := function ( .... )

I cannot assume that the value of object1 and object2 before the call are
meaningless, because they'll both be implicitly passed as parameters to
the function, and the function could be doing whatever it pleases with
these objects.
Yes. The same as it is now. So, on that subject my suggestion
does not change anything. Its not better in that sense and
also not worse...
By convention, the functions should not
return objects that they created anyway.
The main point is that the generated code
is "EXACTLY" the same as in case of:
procedure ComputeABC(p1,p2, a, b, c);
The only difference added is some error
checking and the ability to denote what is
input or output.....
The suggestion does not affect code behaviour.
It only affects the syntax by improving on readability.
About error checks:
- You can request all simple types in the result section
to be specified as out or var parameters.
- objects may not be passed by reference
What you suggest is to restrict the result section
in such a way that it would accept only simple
types which would end the ambiguoty with the
objects, but also really kill off the power of the
syntax.
This is because functions dont return objects at all,
because they should not create them and you dont
pass them as parameters to be returned as a result
either.
I suggest to leave the object ambigouty part as
it has always been and wait for somebody else to make
a suggestion on that part :)
Regards!
Atmapuri
 

Re: Maybe something to vote for...

Atmapuri writes:
Quote
Of course it would have been as clean :) Declaration is just:
function ComputeABC(p1: t1; p2: t2): (var a: boolean; var c:
integer); begin
a := true;
c := 1;
end;
(YourBool, YourInteger) := ComputeABC(p1,p2);
You're right, the function itself is as clean. But calling it isn't
quite as nice as "if MyFunction then...". Unless there's some extreme
compiler magic, you couldn't "if" a function that returned multiple
values.
Still, using something like
(YourBool, YourInteger) := ComputeABC(p1,p2);
If YourBool then DoSomethingWith (YourInteger);
would have been a very acceptable approach, too!
 

Re: Maybe something to vote for...

Quote
(object1, object2) := function ( .... )

I cannot assume that the value of object1 and object2 before the call
are meaningless,
I like the syntax, but it should behave like normal results do, just that we can
have a tuple of results. So it should behave like the Result variable we have
now, except that we can
have several result variables. I.e. the results are simply putted on the stack
or in registers and the assigment is done in the caller not the callee.
// the function (callee) puts the results on the stack or in registers
function ( .... )
// the assignment is done by the caller which picks the values from the
// registers or stack and saves them into object1 and object2
(object1, object2) :=
That would mean we have no problems with references and we don't need to worry
about initial values: object1, object2 and result1 and result2 are different.
object1 =result1 and object2=result2 only after the assignment (i.e. after the
function evaluated).
 

Re: Maybe something to vote for...

Quote
(a,b,c) := ComputeABC(param1, param2);
function ComputeABC(p1: t1; p2: t2): (a,b,c: t3);
begin
end;
I like your syntax but, like I said in the response to Eric, I think it would be
better to not treat a,b,c as references.
One possiblity would be that the compiler implicitly converts a,b,c to a record.
So
(a, b, c) := ComputeABC(param1, param2);
wouldn't be equivalent to
ComputeABC(p1,p2, ref a, ref b, ref c);
but to
TResultType = record
a, b, c
end;
(a,b,c) := ComputeABC(param1, param2);
where (a,b,c) implicitly defines a record.
So things like
var
value, value2: TResultType;
a, b, c: Integer;
begin
(a, b, c) := value;
end;
should be possible and mean the same as
value2 := value;
 

Re: Maybe something to vote for...

Hi Mal,
I like your implicit record idea. Then you could use function as the name,
otherwise,
if they are refs, I think it should be procedure, as in:
procedure ComputeABC(p1: t1; p2: t2): (a,b,c: t3);
However, please don't support it both ways, as it would then be
impossible to know what (a, b, c) := ComputeABC(param1, param2);
represented. :-)
-- Larry Maturo
"Mal Hrz" <XXXX@XXXXX.COM>writes
Quote
>(a,b,c) := ComputeABC(param1, param2);

>function ComputeABC(p1: t1; p2: t2): (a,b,c: t3);
>begin
>end;

I like your syntax but, like I said in the response to Eric, I think it
would be
better to not treat a,b,c as references.

One possiblity would be that the compiler implicitly converts a,b,c to a
record.

So
(a, b, c) := ComputeABC(param1, param2);
wouldn't be equivalent to
ComputeABC(p1,p2, ref a, ref b, ref c);

but to

TResultType = record
a, b, c
end;
(a,b,c) := ComputeABC(param1, param2);

where (a,b,c) implicitly defines a record.
So things like
var
value, value2: TResultType;
a, b, c: Integer;
begin
(a, b, c) := value;
end;
should be possible and mean the same as
value2 := value;



 

Re: Maybe something to vote for...

Michael Baytalsky writes:
Quote
if (a := func(b)) <>'' then
Show(a);

This especially make sense in iterations:

while (cur := c.Next) <>nil do
cur.dosomething;

This reads better then
cur := c.Next;
while cur <>nil do
begin
cur.dosomething;
cur := c.Next;
end;
Please no. Or, at a minimum, make it a compiler option and default it to
OFF.
IME, this particular "feature" has lead to more bugs in C++ code than any
other C++ "feature". At least, IME.
Of course, in both of your examples, you're forgetting the "first" element.
Jon
 

Re: Maybe something to vote for...

Ryan J. Mills writes:
Quote
As a touch typist it takes me maybe 20 (?) seconds more to type
all six lines versus the 2 you typed.
With BDS 2006 and Live Templates, we can set up a template that limits the
keystrokes required to the same as the C++ version.
However, I don't think Michael was talking about ease of typing. I think
he seriously meant ease of reading. Which I just can not agree.
While I can read it /quicker/ the first time, it is neither easier nor
faster for me because I typically read it at least one, if not two, more
times to make sure I understand what the original programmer was doing.
Then the time I spend cussing because he made me work so hard... :D
 

Re: Maybe something to vote for...

"Hi!
Quote
(a, b, c) := ComputeABC(param1, param2);
wouldn't be equivalent to
ComputeABC(p1,p2, ref a, ref b, ref c);
If a,b,c are simple types (integer, boolean, etc..),
then they must be by reference. If they are objects
or pointers, they may "not" be by reference.
Regards!
Atmapuri
 

Re: Maybe something to vote for...

"Atmapuri" <XXXX@XXXXX.COM>writes
Quote
(a,b,c) := ComputeABC(param1, param2);
How such a function can be declared in a clean way?
Here is one idea:
Perl does this. I could take it or leave it in delphi. I dont use it a lot
in perl, but it can be pretty useful at times, especially when returning,
say, a database row in a function. It makes it quick to assign the column
values to variables.
Maybe something like...
function ComputeABC( p1, p2: integer): (integer, integer, integer)
var
a,b,c: integer;
begin
a := p1 +1;
b := p2 + 1;
c := p1 + p2;
return( a, b, c);
end;
But you just know people will abuse this royally by using such a feature
when they should be using records or arrays.
 

Re: Maybe something to vote for...

Hi!
Perl is not the only one...
Quote
function ComputeABC( p1, p2: integer): (integer, integer, integer)
var
a,b,c: integer;
begin
a := p1 +1;
b := p2 + 1;
c := p1 + p2;
return( a, b, c);
end;

But you just know people will abuse this royally by using such a feature
when they should be using records or arrays.
I think its great, but smaller steps are required :)
There are a number of options how this construct can be enhanced
and further developed. One thing is to allow the return type
to be an array of objects in Delphi.NET. Consequently you
could pass entire array of the result as a parameter to another
function and without ever declaring an array. Consequently
even an input could be an open array and an open array
could automatically decompose itself to match the function
parameters. Add function overloading to this and... :)
These are all speculation more or less implemented in other
languages.
The current suggestion requires that the function construct can
not be used in expressions (must be on its own line). that is a very
safe and simple thing...
And I have tons of functions returning multiple results in objects,
arrays and strings...
Regards!
Atmapuri
 

Re: Maybe something to vote for...

Quote
If a,b,c are simple types (integer, boolean, etc..),
then they must be by reference.
Why?
function Add(p1, p2: Integer): Integer;
begin
Result := p1 + p2;
end;
var
b: Integer;
begin
b := Add(2,3);
end;
works fine, you could do this analogically with several return values.
function Div(p1, p2: Integer): Integer*Integer;
begin
Result := (p1 div p2, p1 mod p2);
end;
var
division, modulo: Integer;
begin
(division, modulo) := Div(16, 5);
end;
 

Re: Maybe something to vote for...

That sort of thing is possible ins some declarative languages, but I don't know
how well it would fit in a non-garbage collected imperative language.
You may be able to do some stuff like that with Linq, but that would require you
to swallow your pride and embrace .NET :-)
Cheers,
Jim Cooper
_____________________________________________
Jim Cooper XXXX@XXXXX.COM
Skype : jim.cooper
Tabdee Ltd www.tabdee.ltd.uk
TurboSync - Connecting Delphi to your Palm
_____________________________________________
 

Re: Maybe something to vote for...

Jim Cooper writes:
Quote
You may be able to do some stuff like that with Linq, but that would require
you to swallow your pride and embrace .NET :-)
And change the language.
 

Re: Maybe something to vote for...

Hi!
Quote
You may be able to do some stuff like that with Linq, but that would
require you to swallow your pride and embrace .NET :-)
Well, I have been working in .NET for two years now. I have nothing
for or against it, except when being sold for something that is not.
Regards!
Atmapuri