EndProcedure value

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
Roger Hågensen
User
User
Posts: 47
Joined: Wed Mar 25, 2015 1:06 pm
Location: Norway

EndProcedure value

Post by Roger Hågensen »

Allow EndProcedure to accept a value.

This would make these two examples equivalent:

Code: Select all

Procedure.i Test(input.i)
  Protected result.i = 0
  If input = 5
    result = 1
  EndIf
  ProcedureReturn result
EndProcedure

Code: Select all

Procedure.i Test(input.i)
  Protected result.i = 0
  If input = 5
    result = 1
  EndIf
EndProcedure result
For those curious what the point of supporting this is, then it will not just save you one line of source code.
PureBasic (under the hood) Does a ProcedureReturn 0 for all procedures. So with the first example there are actually two ProcedureReturns.
I forget how many (assembly) lines of code that is but it's at least 1 or two lines of code.
Now this should not affect performance, but it's code that is never used.

I thought about asking if the compiler could automatically drop the under the hood procedurereturn if the last line of code was a ProcedureReturn.
But as EndProcedure is not used for anything else and adding the value to that will simplify the parsing of the code versus checking for the last used ProcedureReturn.

"EndProcedure result" as I suggest here will replace the under the hood hidden ProcedureReturn.


Now it's been a while since I last looked at the assembly output of PureBasic, but as far as I know the compiler does not optimize that hidden procedurereturn away currently (correct me if I'm wrong).
4 music albums under CC BY license available for free (any use, even commercial) at Skuldwyrm.no
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: EndProcedure value

Post by DontTalkToMe »

I'm sure (no, I'm not really, it's just a figure of speech) I'm not alone considering horrid the idea of putting the return value outside the body of the procedure, which is delimited by Procedure/EndProcedure :shock:

In any case this is the code generated:

Code: Select all

; ProcedureReturn result
  MOV    eax,dword [esp]
  JMP   _EndProcedure1
; EndProcedure
_EndProcedureZero1:
  XOR    eax,eax
_EndProcedure1:
  ADD    esp,4
  POP    ebx
  RET    4
After _EndProcedureZero1: there is the usual exiting code returning 0 (the one you mentioned), and in this specific case the XOR is skipped to reach just the "returning part" with the value in eax at the cost of a jump.

Clearly this code it's not needed but *I* wouldn't bother touching it in *PB*, maybe if this were the code generated by an optimizing compiler.

There are bigger problems (such as bugs) not addressed anyway and this looks so unimportant to me compared to the rest.
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: EndProcedure value

Post by Tenaja »

This looks like a PowerBasic wish...

I like it the way it is. There's no benefit to eliminating the ProcedureReturn command.
User avatar
Roger Hågensen
User
User
Posts: 47
Joined: Wed Mar 25, 2015 1:06 pm
Location: Norway

Re: EndProcedure value

Post by Roger Hågensen »

Tenaja wrote:This looks like a PowerBasic wish...

I like it the way it is. There's no benefit to eliminating the ProcedureReturn command.
I never said to eliminate ProcedureReturn, there is benefit in using ProcedureReturn to exit a procedure directly from elsewhere in the procedure (you can have multiple ProcedureReturn in a procedure).
I'm only talking about the case when you do:

Code: Select all

ProcedureReturn value
EndProcedure
which could become (optionally, you are not forced to use it after all):

Code: Select all

EndProcedure value
Which should allow the PB team to re-cycle _EndProcedureZero and get rid of one XOR and one JMP.
DontTalkToMe wrote:I'm sure (no, I'm not really, it's just a figure of speech) I'm not alone considering horrid the idea of putting the return value outside the body of the procedure, which is delimited by Procedure/EndProcedure :shock:
It is not outside, it is at the end of EndProcedure, this is no different than Enumeration having a optional value after it.
DontTalkToMe wrote:There are bigger problems (such as bugs) not addressed anyway and this looks so unimportant to me compared to the rest.
And what does that have to do with this feature request? I've been around this forum for over 10 years and I can not recall once telling others that their feature request is unimportant and should be put aside for bug fixing.
I also doubt that the PB team would ignore a bug so they can add a feature, that is not how development works. They are capable of doing both.
Tenaja wrote:This looks like a PowerBasic wish...
If you say so, I've never used PowerBasic so I got no idea what you are referring to.
If another language does this then perhaps you can enlighten me on how it works (/and if it works well or poorly, is the resulting code more/less efficient because of it?)
DontTalkToMe wrote:Clearly this code it's not needed but *I* wouldn't bother touching it in *PB*, maybe if this were the code generated by an optimizing compiler.
Please do not hijack this request to be about a optimizing compiler, I believe there exist at least one prior thread about that.
4 music albums under CC BY license available for free (any use, even commercial) at Skuldwyrm.no
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: EndProcedure value

Post by DontTalkToMe »

Roger Hågensen wrote: It is not outside, it is at the end of EndProcedure
Then it is outside. Procedure / EndProcedure it's a code block, so after EndProcedure it would be outside.
Roger Hågensen wrote: this is no different than Enumeration having a optional value after it.
So it is different. Enumeration is not EndEnumeration. The optional value is inside the Enumeration/EndEnumeration block.

Roger Hågensen wrote: And what does that have to do with this feature request?
I've explained, but you have a different view from mine about the PB development status in general. So that's probably why you find my remark inopportune. Forget about it.
Roger Hågensen wrote: Please do not hijack this request to be about a optimizing compiler, I believe there exist at least one prior thread about that.
I don't understand. Doesn't look like hijacking to me.
I was just saying I could understand removing a little jump and a xor if this were an optimizing compiler. It would be funny to find this code in that case.
But since it's not the case, and since there are many instances of code which could be optimized by the same degree or more elsewhere in PB, I see this little change extremely marginal and frankly useless. Who should care about a wasted xor and a jump, moreover if not inside a loop ? Who cares. There is no practical reason.

But I'm not the one deciding about this, so don't need to worry about my little remarks. I'm replying just because you formulated some questions, and said the two things at the top which are not true in my opinion (it's outside, it's the same).

It's fair to express some opinions about a feature request, your request still exist and it's still being read by the devs.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: EndProcedure value

Post by Dude »

To the OP: what happens when ProcedureReturn is used multiple times in a procedure to exit? You do know that can be done, right? So what would happen with EndProcedure in that case?
Little John
Addict
Addict
Posts: 4779
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: EndProcedure value

Post by Little John »

Roger Hågensen wrote:For those curious what the point of supporting this is, then it will not just save you one line of source code.
PureBasic (under the hood) Does a ProcedureReturn 0 for all procedures. So with the first example there are actually two ProcedureReturns.
I forget how many (assembly) lines of code that is but it's at least 1 or two lines of code.
Now this should not affect performance, but it's code that is never used.

I thought about asking if the compiler could automatically drop the under the hood procedurereturn if the last line of code was a ProcedureReturn.
I think that would be the best approach. Problems (if this is a problem at all) that exist "under the hood" should not be solved "above the hood".
Roger Hågensen wrote:I never said to eliminate ProcedureReturn, there is benefit in using ProcedureReturn to exit a procedure directly from elsewhere in the procedure (you can have multiple ProcedureReturn in a procedure).
I'm only talking about the case when you do:

Code: Select all

ProcedureReturn value
EndProcedure
which could become (optionally, you are not forced to use it after all):

Code: Select all

EndProcedure value
Yes, this suggested feature could not replace ProcedureReturn, but would exist additionally.
I always like it when things are as simple as possible, and an additional way of returning a value from a procedure is not needed.
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: EndProcedure value

Post by Tenaja »

I find this feature a bit annoying when looking at other code that has it. However, after thinking about it (and trying not to be closed-minded), I do see some merits to a new keyword, if it were implemented in a manner similar to this:

Code: Select all

    Procedure.i Test(input.i)
      If input = 5
        ProcedureResult = 1
      EndIf
    EndProcedure
Note the "Procedure.i" declares the datasize of ProcedureResult, so you eliminate the need for its declaration. Like all other variables, ProcedureResult = 0 until changed. One (rather minor) disadvantage to this is that for the easiest implementation (considering it is a one-pass compiler) it would require an additional variable to be allocated for all procedures that return a value, whether it is utilized or not.
Bo Marchais
User
User
Posts: 61
Joined: Sun Apr 03, 2016 12:03 am

Re: EndProcedure value

Post by Bo Marchais »

HOLD THE PRESSES!!!! (lifted from yet another request for simplified syntax elsewhere in the wishlist)

With only a few cc's of sarcasm, Dude responded to some poster. Dude wrote:
what happens when ProcedureReturn is used multiple times in a procedure to exit? You do know that can be done, right?
Please tell me I'm dreaming. Does he mean (as i assume) you could use ONE of several ProcedureReturns in a Procedure... or does he mean I can return more than one result? It sounds preposterous, since I can't figure out how one would assign more than one var. And yes, I know I can pass an array, or a map... but can we return multiple vars? I can't find examples.

ie:
a,b,c = someprocedure(foo)

Not possible in purebasic, right?
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: EndProcedure value

Post by Tenaja »

Bo Marchais wrote:a,b,c = someprocedure(foo)
Not possible in purebasic, right?
No, not possible.
User avatar
Roger Hågensen
User
User
Posts: 47
Joined: Wed Mar 25, 2015 1:06 pm
Location: Norway

Re: EndProcedure value

Post by Roger Hågensen »

DontTalkToMe wrote:
Roger Hågensen wrote: It is not outside, it is at the end of EndProcedure
Then it is outside. Procedure / EndProcedure it's a code block, so after EndProcedure it would be outside.
Ok, I did not pick the best example how about but

Code: Select all

Repeat
Until xxxx
then?
So PureBasic isn't that "pure" as your eyes see it.
DontTalkToMe wrote: Who should care about a wasted xor and a jump, moreover if not inside a loop ? Who cares. There is no practical reason.
Less lines of code means less space wasted in the CPU cache (no idea how it affect if at all the branch predictors). And considering that many use call procedures in a loop it does matter in the end. THe Bind stuff makes use of procedures for example.
DontTalkToMe wrote:Forget about it.
Considering how succint your user name is, I think I'll heed it's advice.
Dude wrote:To the OP: what happens when ProcedureReturn is used multiple times in a procedure to exit? You do know that can be done, right? So what would happen with EndProcedure in that case?
Please see my first line/paragraph in the 4th post:
"I never said to eliminate ProcedureReturn, there is benefit in using ProcedureReturn to exit a procedure directly from elsewhere in the procedure (you can have multiple ProcedureReturn in a procedure)."

Let me re-iterate. The "hidden" return will only be replaced if "EndProcedure value" is used.
All use of ProcedureReturn inside the procedure will continue to function just like they do today.

Let me simplify this further. "EndProcedure value" let you replace the xor eax,eax with a mov eax, value

That's it. That is the only thing I'm suggesting, I'm not suggesting to change ProcedureReturn at all.
Bo Marchais wrote:HOLD THE PRESSES!!!!
...
Please tell me I'm dreaming. Does he mean (as i assume) you could use ONE of several ProcedureReturns in a Procedure...
Tenaja is right, not possible to return an array.

However using multiple ProcedureReturns is a very effective way to reduce if/then/else/endif nesting.

Instead of doing If result = #True and then do your code you can do a If result = #False and then use a ProcedureReturn.

With less nesting a CPU should be able to cache better (as the nesting is not so deep any more).
Depending on how you code you may even be able to drop a Else Endif block thereby getting rid of a jump/condition.
In theory a smart processor might be able to see all the If's that lead to a ProcedureReturn and could do parallel evaluation of the conditions/values.

I have made a rule for myself that I should never go more than one or two deep in If Endif nesting, if I go deeper than I'm doing something wrong and should re-think my code.

It was this thinking that led me to remember about the xor eax,eax going unutilized when you use a ProcedureReturn at the end of a procedure. Wouldn't it be cool if that could be changed to a mov instead when appropriate?

Although this is veering off-topic I'd just like to mention that your wish of a "a,b,c = someprocedure(foo)" is not directly possible, so my advice is to return a error code (0 if no error, and non-zero if a error) and instead pass a pointer to a structure to the procedure when you call it, that way you can populate/change the values from within the procedure and "return" them. A lot of Windows API stuff do it this way.
4 music albums under CC BY license available for free (any use, even commercial) at Skuldwyrm.no
Bo Marchais
User
User
Posts: 61
Joined: Sun Apr 03, 2016 12:03 am

Re: EndProcedure value

Post by Bo Marchais »

I basically do this now... using global vars. It's not my preferred way, but it works.
I really need to get under the hood of Purebasic, but my dream is to not do that!

I am the same way - I hate using elseif.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: EndProcedure value

Post by Dude »

Here's a dirty hack that may be of interest:

Code: Select all

Macro EndProcedureWith(result)
  ProcedureReturn result
  EndProcedure
EndMacro

Procedure test(num)
  num+1
EndProcedureWith(num)

Debug Test(1) ; Outputs 2
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: EndProcedure value

Post by DontTalkToMe »

Roger Hågensen wrote: Ok, I did not pick the best example how about but

Code: Select all

Repeat
Until xxxx
then?
So PureBasic isn't that "pure" as your eyes see it.
You may be horrified to see PB through my eyes :)

OK, I get your point above, Still I wouldn't put a clear-cut code unit like procedure-endprocedure on the same plane of repeat-until or for-next.
You can even write for i - next i (so i is after the next).
Anyway is subjective, I simply wouldn't like EndProcedure Returnvalue.

Roger Hågensen wrote: Less lines of code means less space wasted in the CPU cache (no idea how it affect if at all the branch predictors).
Yes, and I still believe the impact of those two instructions is irrelevant. Especially in the case of PB. I have nothing against optimizing the code generated by the compiler in general, when all the rest is perfect as it is and there is not something very useful missing.
In the specific I just don't think it will happen, and if it will happen it will have no practical consequences at all, and so probably it's not a bad idea to not do it.
Anyway anyone can try to code the proposed exit code in asm, and compare the two versions in a real program. The optimized one and the current one.
And see what happens. Is your program unrecognizable now ? Your game jumped from 50 to 60 fps ? Is it more responsive ? Do you notice any difference at all ? Can you now crack the password which was before uncrakable ? Or do you have to do a synthetic bench created ad hoc of a billion of loops to be able to measure a difference ?
This is not a 6502 1MHz world anymore, who cares about those two instructions when one should concentrate on the appropriate algorithmic choice or in writing better hi level code (much more important with a non optimizing compiler like PB).
Roger Hågensen wrote: And considering that many use call procedures in a loop it does matter in the end.
Hypothetically (but again not practically) if the procedure is empty.
Then the two instructions would amount to a small percentage of the code (the almost-equivalent-to-a-stack-frame build and release and that exit code).
But since it's very unlikely to loop an empty procedure, the weight of those two instructions count always less.
I find absurd (again in practice, not in absolute terms) even considering these kind of alteration to the code generated by PB, with all the other things that could be done and are sorely missed and yet not happening at the moment.
If this is implemented (simply by optimizing the code generated I hope and not adding that Retunvalue outside the body of the procedure) anyone will notice it ? I don't think so in a world where procedures do something and are not empty, and I would say even in a world of empty procedures.
Roger Hågensen wrote: Considering how succint your user name is, I think I'll heed it's advice.
I understand you. After all the username was not chosen randomly!
That doesn't mean I will not talk to you even if you ignore me, it's not IWillNotTalkToYou :lol:
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: EndProcedure value

Post by collectordave »

-1
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
Post Reply