Recent

Author Topic: [SOLVED] Is there a best method for returning a function value?  (Read 22342 times)

440bx

  • Hero Member
  • *****
  • Posts: 6542
Re: Is there a best method for returning a function value?
« Reply #30 on: April 14, 2020, 04:04:16 pm »
Yes. of course, but if a good alternative is at hand then it is better to avoid recursion.
I think the main problem with the way a lot of recursive algorithms are implemented is that often the programmer neglects to put checks on the recursion depth (which is also often the reason they use the recursive algorithm.) 

As you said, if a good alternative is available then, implementing a "flat", i.e, non-recursive, algorithm is fine but, there are some problems that have elegant and concise recursive algorithms as solutions and the equivalent "flat" algorithm is not nearly as elegant nor concise.

Compilers are notorious for using recursive algorithms for one thing or another when there are very decent non-recursive solutions to attain the same goal.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

soerensen3

  • Full Member
  • ***
  • Posts: 213
Re: Is there a best method for returning a function value?
« Reply #31 on: April 14, 2020, 11:03:53 pm »
I understand the criticism about goto and exit but they make sense sometimes.

Which of those versions is easiest to read?
Code: Pascal  [Select][+][-]
  1. function TFPList.IndexOf(Item: Pointer): Integer;
  2.  
  3. Var
  4.   C : Integer;
  5.  
  6. begin
  7.   Result:=0;
  8.   C:=Count;
  9.   while (Result<C) and (Flist^[Result]<>Item) do
  10.     Inc(Result);
  11.   If Result>=C then
  12.     Result:=-1;
  13. end;      
  14.  

Code: Pascal  [Select][+][-]
  1. function TFPList.IndexOf(Item: Pointer): Integer;
  2. var
  3.   i: Integer;
  4. begin
  5.   Result:=-1;
  6.   for i:= 0 to Count - 1 do
  7.     if (Flist^[i]<>Item) then begin
  8.       Result:= i;
  9.       break;
  10.     end;
  11. end;      
  12.  

Or even

Code: Pascal  [Select][+][-]
  1. function TFPList.IndexOf(Item: Pointer): Integer;
  2. var
  3.   i: Integer;
  4. begin
  5.   Result:=-1;
  6.   for i:= 0 to Count - 1 do
  7.     if (Flist^[i]<>Item) then
  8.       Exit( i );
  9. end;      
  10.  
Lazarus 1.9 with FPC 3.0.4
Target: Manjaro Linux 64 Bit (4.9.68-1-MANJARO)

ASerge

  • Hero Member
  • *****
  • Posts: 2503
Re: Is there a best method for returning a function value?
« Reply #32 on: April 15, 2020, 07:36:05 am »
Which of those versions is easiest to read?
For me, all versions are very clear. If only in the first I removed the extra lines and changed the case of VB like reserved word to lower case (but FPS admins do not like refactoring, because comparison tools will give out a lot of differences :-X).
And in the last example, I would move the "Result := -1" operator to the end, so it is more logical.

munair

  • Hero Member
  • *****
  • Posts: 887
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: Is there a best method for returning a function value?
« Reply #33 on: April 15, 2020, 08:41:50 am »
There are "goto's" happening behind the scenes all the time. Only the jump range is limited to control flows and scopes (understandably).
Code: Text  [Select][+][-]
  1. function Sign(number): byte
  2.   var result: byte = 0;  // if not default return value
  3.  
  4.   if number = 0 then
  5.     goto MyFunc_Exit;  // jump limited to scope
  6.   end if
  7.  
  8.   result = -1;
  9.  
  10.   if number < 0 then
  11.     goto MyFunc_Exit;
  12.   end if
  13.  
  14.   result = 1;
  15.  
  16. MyFunc_Exit:
  17.   Sign = result;
  18. end function

Of course, IF .. ELSE IF .. branches are preferred, but the above code mirrors exactly what happens when translated to assembler:
Code: ASM  [Select][+][-]
  1.     mov     result, 0
  2.     mov     eax, number
  3.     push    eax
  4.     mov     eax, 0
  5.     pop     edx
  6.     cmp     edx, eax
  7.     jz      .Exit              ; jump (return 0)
  8.     mov     result, -1
  9.     jl      .Exit              ; jump (return -1)
  10.     neg     result             ; (return 1)
  11.   .Exit:
  12.     mov     eax, result
It's only logical.

dbannon

  • Hero Member
  • *****
  • Posts: 3826
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Is there a best method for returning a function value?
« Reply #34 on: April 15, 2020, 09:23:29 am »

So far, I have come across 3 different methods of returning a value from a function. There may be more, but I haven't seen them yet:

Jumping (definitely not GOTO-ing) back to the original question, you missed one -

Code: Pascal  [Select][+][-]
  1. function %name%(param1: type1; param2: type2; ...): type;
  2.   var  
  3.     declarations;
  4.  
  5. begin
  6.    result := value;
  7.    < statements >
  8.    exit;
  9.    < statements >
  10. end;

That particular varient does highlight the different between pascal.result and C.return IMHO.  Result can be used to set a default return condition that may or may not be changed.

And while we all agree that 'Result :=' is easier to read than the 'old school'  '%FunctionName% :=' model, it's fun to  note that FPC, unless you set its mode to, eg object pascal, will tell you that Result is an unknown identifier ....

Davo
Lazarus 4, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

munair

  • Hero Member
  • *****
  • Posts: 887
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: Is there a best method for returning a function value?
« Reply #35 on: April 15, 2020, 09:41:44 am »
Jumping (definitely not GOTO-ing)

They do the same thing; it is just a name preference. Never thought programmers could have such strong taste. %)

Quote
Result can be used to set a default return condition that may or may not be changed.

While I understand the arguments against function %name%= ... syntax, it does make it very clear what is happening. Anyone even new to Pascal programming would understand it, while a built-in default variable such as 'result' is not because it is not immediately clear where it comes from or how it is declared. Moreover, it may clash with preferred variable naming.

While there may be some advantage in being able to set a function's return value independent of the function's name, a variable named 'result' isn't the best solution IMHO. I say *some* because the argument that a function's name may change is weak; if it does, there are likely several or many references that will have to be renamed across a project anyway. The one or few inside the function's body won't make a difference.
« Last Edit: April 15, 2020, 09:52:47 am by Munair »
It's only logical.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6398
  • Compiler Developer
Re: Is there a best method for returning a function value?
« Reply #36 on: April 15, 2020, 09:56:12 am »
The main disadvantage of using the function name in Pascal is if you have a function with no arguments (or default arguments) and you use the function name inside an expression (not on the left side of an assignment): is it a call or a read of the result variable? This has lead to problems and bugfixes in the past, because TP and Delphi handle this a bit differently...

440bx

  • Hero Member
  • *****
  • Posts: 6542
Re: Is there a best method for returning a function value?
« Reply #37 on: April 15, 2020, 10:00:28 am »
<snip> is it a call or a read of the result variable? This has lead to problems and bugfixes in the past
That's definitely a problem with the "function name".  Would you entertain the idea of adding a "modeswitch" (or something else) to make the parentheses always required ?  That would ensure they aren't omitted by oversight or mistake.  (I always put the () but occasionally, I forget them and, it would be nice if the compiler flagged it as an error.)
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

eljo

  • Sr. Member
  • ****
  • Posts: 468
Re: Is there a best method for returning a function value?
« Reply #38 on: April 15, 2020, 10:02:50 am »
Jumping (definitely not GOTO-ing)

They do the same thing; it is just a name preference. Never thought programmers could have such strong taste. %)

Quote
Result can be used to set a default return condition that may or may not be changed.

While I understand the arguments against function %name%= ... syntax, it does make it very clear what is happening. Anyone even new to Pascal programming would understand it, while a built-in default variable such as 'result' is not because it is not immediately clear where it comes from or how it is declared. Moreover, it may clash with preferred variable naming.

While there may be some advantage in being able to set a function's return value independent of the function's name, a variable named 'result' isn't the best solution IMHO. I say *some* because the argument that a function's name may change is weak; if it does, there are likely several or many references that will have to be renamed across a project anyway. The one or few inside the function's body won't make a difference.
My experience is the exact opposite. I find the use of result clear and to the point even the variable name is well chosen the function name on the other hand I had to look it up on the help files when I first encountered it to make sure I did not misunderstand.

Just to avoid any confusion, I'm only saying that your reasoning is tainted by your own habits and even if it isn't it is a based on a habit building process which will change from generation to generation. Its not a very strong case for change unless you count perpetual change.

munair

  • Hero Member
  • *****
  • Posts: 887
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: Is there a best method for returning a function value?
« Reply #39 on: April 15, 2020, 10:25:52 am »
The main disadvantage of using the function name in Pascal is if you have a function with no arguments (or default arguments) and you use the function name inside an expression (not on the left side of an assignment): is it a call or a read of the result variable? This has lead to problems and bugfixes in the past, because TP and Delphi handle this a bit differently...
If it is not on the left side, then it should be interpreted as a recursive call, *always*. It is clear and obvious that a function name should never be used as a variable (because it isn't), not even inside its own body. There is no ambiguity here.

In my first Pascal programming days I even hesitated to use the built-in result variable as a normal variable that can be changed and manipulated anywhere inside the function's body, because I had this misplaced but persistent idea that it might affect the function prematurely.
« Last Edit: April 15, 2020, 11:22:16 am by Munair »
It's only logical.

440bx

  • Hero Member
  • *****
  • Posts: 6542
Re: Is there a best method for returning a function value?
« Reply #40 on: April 15, 2020, 10:28:28 am »
While I understand the arguments against function %name%= ... syntax, it does make it very clear what is happening. Anyone even new to Pascal programming would understand it, while a built-in default variable such as 'result' is not because it is not immediately clear where it comes from or how it is declared. Moreover, it may clash with preferred variable naming.

While there may be some advantage in being able to set a function's return value independent of the function's name, a variable named 'result' isn't the best solution IMHO. I say *some* because the argument that a function's name may change is weak; if it does, there are likely several or many references that will have to be renamed across a project anyway. The one or few inside the function's body won't make a difference.
Both methods have advantages and disadvantages.  As you pointed out, assigning a value to the function makes the intention crystal clear but, it's not very flexible and if the function name is changed then it has to be changed there too.

Using "result" is more flexible and powerful (the optimizer can see it as just another variable) but, the uninitiated may not realize that "result" is the function's return value and not another local (or global) variable.

All taken into account, using "result" seems to be more advantageous.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

zamronypj

  • Full Member
  • ***
  • Posts: 140
    • Fano Framework, Free Pascal web application framework
Re: Is there a best method for returning a function value?
« Reply #41 on: April 15, 2020, 12:58:38 pm »
I wish that "result" variable can be mapped to another more meaningful name.

Code: [Select]
if result then
begin
end;

Above code cannot  self document purpose of "result" variable.
« Last Edit: April 15, 2020, 01:01:33 pm by zamronypj »
Fano Framework, Free Pascal web application framework https://fanoframework.github.io
Apache module executes Pascal program like scripting language https://zamronypj.github.io/mod_pascal/
Github https://github.com/zamronypj

Zoran

  • Hero Member
  • *****
  • Posts: 1988
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Is there a best method for returning a function value?
« Reply #42 on: April 15, 2020, 03:21:31 pm »
Which of those versions is easiest to read?
For me, all versions are very clear.

When function body is short, it is always easy to follow.
For so short function body, even this would be easy to follow:

Code: Pascal  [Select][+][-]
  1. function TFplist.IndexOf(Item: Pointer): Integer;
  2.  
  3. label LoopStart;
  4. label ResultFound;
  5. label ResultNotFound;
  6. label FunctionEnd;
  7.  
  8. var
  9.   C, I : Integer;
  10.  
  11. begin
  12.   C:=Count;
  13.  
  14.   I := 0;
  15.   LoopStart:
  16.   if I >= C then
  17.     goto ResultNotFound;
  18.  
  19.   if Flist^[I] = Item then
  20.     goto ResultFound;
  21.  
  22.   Inc(I);
  23.   goto LoopStart;
  24.  
  25.   ResultFound:
  26.   Result := I;
  27.   goto FunctionEnd;
  28.  
  29.   ResultNotFound:
  30.   Result := -1;
  31.  
  32.   FunctionEnd:
  33. end;
  34.  

So, keep your routines short, as much as you can!

Huh, It took me some time, I didn't even remember the correct syntax for declaring and using labels... :-[
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

ASerge

  • Hero Member
  • *****
  • Posts: 2503
Re: Is there a best method for returning a function value?
« Reply #43 on: April 15, 2020, 08:26:49 pm »
When function body is short, it is always easy to follow.
For so short function body, even this would be easy to follow:
But I already have difficulties with this code. I need to see what, how, and where to go.

munair

  • Hero Member
  • *****
  • Posts: 887
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: Is there a best method for returning a function value?
« Reply #44 on: April 15, 2020, 09:07:13 pm »
As I said earlier, a function name on the right side of the equation should always be interpreted as a (recursive) call. I did some testing both with the compiler I am building and also with the FreeBasic compiler. The following FreeBasic code will result in a segmentation fault crash because of an infinite recursive loop. The compiler does not even complain when parsing code like this:
Code: FreeBasic  [Select][+][-]
  1. declare function five() as integer
  2.  
  3. print five
  4. end
  5.  
  6. function five() as integer
  7.        
  8.   return five
  9.  
  10. end function

At least the SharpBASIC compiler raises a 'potential infinite loop 'five' detected' warning. I have not yet tested FPC. But as you can see, there is a lot more to returning a function result than meets the eye.
It's only logical.

 

TinyPortal © 2005-2018