Page 2 of 2

Re: ProcedureReturn returning more than one value

Posted: Tue Aug 31, 2010 7:59 pm
by charvista
@Jamirokwai
Not so bad idea! :o
Full speed? In some situations like in a long loop and large strings, it might considerably slown down, yes. But the idea to put every element in one string separated with a choosen delimiter is a good workaround. And with StringField the contents is easily loaded.
The mix of types of variables is not a problem:

Code: Select all

#SEP=Chr(166); not the same as Chr(124) !!!!

Procedure.s TextInfo(Text.s)
    I1=Len(Text)
    For i=1 To Len(Text)
        If Mid(Text,i,1)=" "
            I2+1
        EndIf
    Next
    Out.s=Str(I1)+#SEP+Str(I2)+#SEP
    ProcedureReturn Out
EndProcedure

Text.s="The quick brown fox jumps over the lazy dog"
Ti.s=TextInfo(Text)
Debug "Text length = "+StringField(Ti,1,#SEP)
Debug "There are "+StringField(Ti,2,#SEP)+" spaces in the text."
:wink:

Re: ProcedureReturn returning more than one value

Posted: Tue Aug 31, 2010 11:48 pm
by blueznl
Well, the idea behind the whole thing is that PureBasic hides complexity from the end-user, whereever possible. So why bother the end user with structures and pointers?

I'd love to do something like:

Code: Select all

Procedure.i,i SpecialFeature( q )
  Protected x , y
  x = q /2
  y = q*2
  ProcedureReturn x,y
EndProcedure

a , b = SpecialFeature( 102 )
As for grammar discussions, some restrictions may be imposed. For example a function call within an evalution may only return one value, ie. this special construction would only be allowed in direct assignments.

Then again, this could be even accomplished by a pre-processor.

Still this being a native feature would be great...

Re: ProcedureReturn returning more than one value

Posted: Wed Sep 01, 2010 12:02 am
by STARGÅTE
this special construction would only be allowed in direct assignments.
then you can use ...

Code: Select all

Procedure.i SpecialFeature( q, *x.Integer, *y.Integer )
  *x\i = q /2
  *y\i = q*2
  ProcedureReturn #True
EndProcedure

SpecialFeature( 102 , @a, @b)
Debug a
Debug b
your idea is only makes sense if you could use it anywhere:

Code: Select all

Procedure.i Add(a, b)
  ProcedureReturn a + b
EndProcedure

Procedure.i,i SpecialFeature( q )
  Protected x , y
  x = q /2
  y = q*2
  ProcedureReturn x,y
EndProcedure

Add( SpecialFeature( 102 , @a, @b) )
and so on:

Code: Select all

x,y = 1,20
and so on:

Code: Select all

x,y = 1,20
a,b = x*x+2,y/2
and so on:

Code: Select all

For x, y = 0, 0 To 10, 10
  Debug x
  Debug y
Next x, y
like:

Code: Select all

For x = 0 To 10
  For y = 0 To 10
    Debug x
    Debug y
  Next y
Next x
This feature is unnecessary!
And the code would be unreadable for other user!

Re: ProcedureReturn returning more than one value

Posted: Wed Sep 01, 2010 8:39 am
by blueznl
Dunno, I beg to disagree :-) The only reason why it's use should be limited is that the compiler must be aware of the number of return parameters. If you would do something like:

Code: Select all

a = SpecialFeature( 1,2 )
... but that function would return two parameters, then the compiler should trigger a warning, or just process the first value returned or something similar. As long as its well defined, it's good.

And be honest, it's all about readability. Using pointers and structs is not very readable. If you want a player's x and y (and you don't have any OOP at hand :-)) this would be the simplest approach:

Code: Select all

  x , y = PlayerPosition( #player1 )
That's quite readable :-)

On the other hand, things like:

Code: Select all

  For x, y = 1 to 10, 2 to 10
    ..
Is exactly the opposite!

So, I beg to disagree with you :-)

Re: ProcedureReturn returning more than one value

Posted: Thu Sep 02, 2010 9:34 pm
by Rescator
DarkDragon wrote:But notice that you can't call ThreadSafeMultiReturn a second time inside the same Thread without loosing the old result and its just leading to bugs if you return the pointer as you might not remember the first part of my sentence.
So it's threadsafe, but not really threadsafe? *laughs*
You can't call that threadsafe at all then as thread safe means exactly that, that the input/output to or from vars or functions are not affected by other threads running at the same time.

This is an example of your example failing, like you mentioned:

Code: Select all

Structure TheStructure
  a.i
  b.i
  c.i
EndStructure

Threaded Result.TheStructure

Procedure.i ThreadSafeMultiReturn(test.i)
  If test=1
	  Result\a = 10
	  Result\b = 20
	  Result\c = 30
  Else
	  Result\a = 11
	  Result\b = 22
	  Result\c = 33
  EndIf
  ProcedureReturn @Result
EndProcedure

*Result.TheStructure = ThreadSafeMultiReturn(1)
*Result2.TheStructure = ThreadSafeMultiReturn(2)

If *Result
  Debug Result\a
  Debug Result\b
  Debug Result\c
Else
  Debug "Failed?"
EndIf
The only real thread safe way is like what Fred and a few others showed earlier. Allocate and pass a pointer to the function,
or allocate inside the function and return a pointer (that you must later free).
Personally I prefer the way Fred showed earlier, and it works great with vars, structures and arrays etc...

Re: ProcedureReturn returning more than one value

Posted: Thu Sep 02, 2010 10:47 pm
by GeBonet
I know there are other method ... But
In this way, what do you think of this?

Code: Select all

;-----------------------------------------------
;
Procedure MonTransfert(MonNom$,Adresse$,Numero, Cas)
  
  If Cas=1
    MonNom$="GeBonet Michel"
    Adresse$="Rue de Londre"
    Numero=335
  ElseIf cas=2 
    MonNom$="Albert LaJoie"
    Adresse$="Avenue des champs Elysés"
    Numero=523
  EndIf
  
EndProcedure 
;
A_MonNom$= "GeBonet Gerhard"
A_Adresse$="Rue de paris"
A_Numero=32
;
For Cas=3 To 1 Step -1
  ;
  MonTransfert(A_MonNom$,A_adresse$,A_Numero, Cas)
  ;
  Debug A_MonNom$   ; Here I am waiting for a response in terms of "CAS"
  Debug A_adresse$
  Debug A_Numero
  
Next cas  
This is possible If the variables passed in "Proceedings MonTransfert (MonNom$, Addresse$, Numero, Case)"
Serve crossing in both directions ...
So non-Global variables are internal To the proceedings except those that can be passed As amended in And get out changed.
As this happened in QBX, Qb etc. ...
:roll:

Re: ProcedureReturn returning more than one value

Posted: Thu Sep 02, 2010 10:52 pm
by Rescator
That is the same as doing this: ;)

Code: Select all

EnableExplicit

Procedure MonTransfert(*MonNom$,*Adresse$,*Numero.Integer,Cas.i)

  If Cas=1
     *MonNom$="GeBonet Michel"
     *Adresse$="Rue de Londre"
     *Numero\i=335
  ElseIf Cas=2
     *MonNom$="Albert LaJoie"
     *Adresse$="Avenue des champs Elysés"
     *Numero\i=523
  EndIf
 
EndProcedure
;
Define MonNom$,Adresse$,Numero.i,Cas.i
MonNom$= "GeBonet Gerhard"
Adresse$="Rue de paris"
Numero=32
;
For Cas=3 To 1 Step -1
  ;
  MonTransfert(@MonNom$,@adresse$,@Numero,Cas)
  ;
  Debug MonNom$   ; Here I am waiting for a response in terms of "CAS"
  Debug adresse$
  Debug Numero
 
Next cas
This is something I've begun doing a lot.
Bur if there are a lot of variables then it's better to use a structure instead as too many params when calling a procedure can eat up too many registers (is this true for PureBasic as well?)

EDIT: oops. fixed a tiny bug with Numero referencing.

Re: ProcedureReturn returning more than one value

Posted: Thu Sep 02, 2010 11:15 pm
by Rescator
But I guess something like the following fake example could be possible,
this is similar to how you would do ByRef in PHP etc.
And @ is not used in procedure params otherwise (that I'm aware of) and as @ is used as ByRef in the reverse way it kinda makes sense,
the only limitation is that this would only work within PureBasic.
While the current use of ByRef works with DLL's etc as you always control manually what happens,
the following example would not work with DLL's or similar as there is no way for PureBasic to know what the ByRef is pointing to.

Code: Select all

EnableExplicit

Procedure MonTransfert(@MonNom$,@Adresse$,@Numero,Cas.i)

  If Cas=1
     MonNom$="GeBonet Michel"
     Adresse$="Rue de Londre"
     Numero=335
  ElseIf Cas=2
     MonNom$="Albert LaJoie"
     Adresse$="Avenue des champs Elysés"
     Numero=523
  EndIf

EndProcedure
;
Define MonNom$,Adresse$,Numero.i,Cas.i
MonNom$= "GeBonet Gerhard"
Adresse$="Rue de paris"
Numero=32
;
For Cas=3 To 1 Step -1
  ;
  MonTransfert(MonNom$,adresse$,Numero,Cas)
  ;
  Debug MonNom$   ; Here I am waiting for a response in terms of "CAS"
  Debug adresse$
  Debug Numero

Next cas

Re: ProcedureReturn returning more than one value

Posted: Fri Sep 03, 2010 12:38 am
by GeBonet
Hi,
That is the same as doing this:
You are right... I now that...!

We can do, all wat we wan, with PB... :D But if may be more simple, wy not ?
My intention, is not using the "Structures" and "pointers" or CopyStructure(*Variable, @DansDll.ModelStruct, ModelStruct) etc...
Only the "Variables"... Like the "Old" Qbasic, Qbx, it was so easy with the "Sub fonction()" and "Function() and Procedure()"...
But, it's just one sugestion.. :wink: It's not absolutely necessary 8)
Good night... Sorry, i go Sleeping.. :D

Re: ProcedureReturn returning more than one value

Posted: Fri Sep 03, 2010 12:12 pm
by charvista
@GeBonet
My intention, is not using the "Structures" and "pointers"
I thought the same when I began programming with PureBasic. Like you and many other people, I was looking for the easy way. :? But when I was forced to use pointers (it is almost impossible to avoid them), I discovered the amazing speed of pointers, and now I like them a lot! :P When I had to work with a large variable in a loop, it became incredibly slow after 500 updates; then I decided to try it with pointers, you can imagine my surprise and excitment when it was still fast after 20,000 updates! :shock: So, it is in your full advantage to work with pointers, mate! :wink:

To come back to my original post now, my wish to return more than one value from a procedure, I now think it is not really necessary. There are enough other ways which are very powerful.

However, another thought is that all variables entered as parameters could be always treated "ByVal", except if entered between parentheses. It was the case in several old "Business Basic"s.

Cheers, Charvista

Re: ProcedureReturn returning more than one value

Posted: Fri Sep 03, 2010 5:18 pm
by GeBonet
@Charvista

Thank's for this answers... I agree with you, but simply to open an additional channel and speaking more clearly.
Image