Pass by reference

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Pass by reference

Post by Mistrel »

We can already do this:

Code: Select all

Procedure That(*This.Integer)
  *This\i=2
EndProcedure

That(@This)
Debug This
But it would be so much simpler if we could do this:

Code: Select all

Procedure That(&This)
  This=2
EndProcedure

That(This)
Debug This
Without pass by reference it's very cumbersome to do something like this, for example:

Code: Select all

Procedure That(*This.Something)
  *This=AllocateMemory(SizeOf(Something))
  *This\a=1
  *This\b=2
  *This\c=3
EndProcedure

Define *This.Something
That(@*This)
Debug *This\a
Debug *This\b
Debug *This\c
We have to do this instead:

Code: Select all

Procedure That(*This.Something)
  *OldAddress=*This
  *This=AllocateMemory(SizeOf(Something))
  *This\a=1
  *This\b=2
  *This\c=3
  PokeI(*OldAddress,*This)
EndProcedure

Define *This.Something
That(@*This)
Debug *This\a
Debug *This\b
Debug *This\c
Something as simple as this would be ideal:

Code: Select all

Procedure That(&*This.Something)
  *This=AllocateMemory(SizeOf(Something))
  *This\a=1
  *This\b=2
  *This\c=3
EndProcedure

Define *This.Something
That(*This)
Debug *This\a
Debug *This\b
Debug *This\c
Or this:

Code: Select all

Procedure That(*This.Something)
  *This=AllocateMemory(SizeOf(Something))
  *This\a=1
  *This\b=2
  *This\c=3
EndProcedure

Define *This.Something
That(&*This)
Debug *This\a
Debug *This\b
Debug *This\c
Am I missing some simple solution here or is this type of parameter passing too complex for PureBasic to handle gracefully?
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I sorry I don't understand what you want to achieve with your second example....

*reads over it half a dozen times*

you mean to create a pointer outside a proc,
and then inside allocate mem and bend the pointer towards it?
oh... and have a nice day.
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post by Hroudtwolf »

How about this?

Code: Select all

Structure tVoid
   v.i
EndStructure

Procedure That ( *Void.tVoid )
  *Void\v = AllocateMemory( SizeOf ( tVoid ) ) 
EndProcedure

Define *This 
That(@*This)
Debug *This
Regards

Wolf
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

Hroudtwolf wrote:How about this?

Code: Select all

Structure tVoid
   v.i
EndStructure

Procedure That ( *Void.tVoid )
  *Void\v = AllocateMemory( SizeOf ( tVoid ) ) 
EndProcedure

Define *This 
That(@*This)
Debug *This
Regards

Wolf
That's no different from the integer method. This still doesn't provide a way to allocate memory for and assign values to the new memory within the function and get it out without the roundabout method I mentioned before.
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post by Hroudtwolf »

This possibility is quite enough.

-1
'Cause, I disapprove of syntax changes.

Regards

Wolf
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

With pass by reference it would be much simpler to break down functions that use pointers like this.

I have several functions that use identical code that should be an a separate function but to do so would make the function difficult to decipher and maintain because of having to address pointers in such a roundabout way.
Hroudtwolf wrote:'Cause, I disapprove of syntax changes.
I admit, it's usefulness isn't obvious unless you start using it on a regular basis.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I'm not sure, but I guess what you want is what are Interfaces and Prototypes for...
oh... and have a nice day.
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

How about this?

It's more awkward than pointers in C or references in C++ because you have to create a structure for the level of indirection rather than just adding on a few extra *'s, but you can do it directly in PB syntax without having to resort to Poke.

Code: Select all

Structure PointerToSomething
    *something.Something
EndStructure

Procedure That(*This.PointerToSomething)
  *This\something=AllocateMemory(SizeOf(Something))
  *This\something\a=1
  *This\something\b=2
  *This\something\c=3
EndProcedure

Define *This.Something
That(@*This)
Debug *This\a
Debug *This\b
Debug *This\c
You'd only really need a couple of levels of indirection at most (usually).
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

Thanks, tinman. That is a much more elegant solution (I knew I was forgetting something obvious) but when looking back at the code months from now I'm afraid it will still be misleading, considering it's a hack on a per-structure basis.

It solves the problem but it still makes the intent more difficult to interpret.
User avatar
bembulak
Enthusiast
Enthusiast
Posts: 572
Joined: Mon Mar 06, 2006 3:53 pm
Location: Austria

Post by bembulak »

Why not use the "shared" keyword?
I really guess it's meant for "passing" by value, because it's used get outside values inside a procedure.
cheers,

bembulak
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

You can't used shared for instances where the address passed is for a user-defined variable.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

Kaeru Gaman wrote:I sorry I don't understand what you want to achieve with your second example....

*reads over it half a dozen times*

you mean to create a pointer outside a proc,
and then inside allocate mem and bend the pointer towards it?
Pass by reference is basically the equivalent functionality of the "shared" keyword but the variable is passed as a parameter instead of being declared statically.

To be more specific, the variable passed by reference is available within the same scope of the function. It means you don't have to pass by-address and then peek/poke/structured pointer your values in.

It's a great convenience, I think. In my opinion it can make code that involves a lot of dynamic allocation and pointer-passing much easier to read and write.
User avatar
USCode
Addict
Addict
Posts: 912
Joined: Wed Mar 24, 2004 11:04 pm
Location: Seattle, USA

Yes please!

Post by USCode »

Mistrel wrote: ... It's a great convenience, I think. In my opinion it can make code that involves a lot of dynamic allocation and pointer-passing much easier to read and write.
+1
I couldn't agree more. Delphi has something similar with the "var" keyword and in VB I believe it's "ByRef".
In my view it makes code clearer as well as being VERY convenient.
Many folks don't want to deal directly with pointers and a simple pass by reference keyword would be much appreciated.
User avatar
Demivec
Addict
Addict
Posts: 4091
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Pass by reference

Post by Demivec »

Mistrel wrote:Am I missing some simple solution here or is this type of parameter passing too complex for PureBasic to handle gracefully?
Mistrel wrote:It's a great convenience, I think. In my opinion it can make code that involves a lot of dynamic allocation and pointer-passing much easier to read and write.
In looking at the examples you provided nothing you did made the code any easier to read. The ways that you suggested to make it easier to write seemed to only involve exchanging the "@" character for an "&" character. That hardly seems helpful or worthwhile.

Side note: IMHO your best bet to making it easier to read is to use more meaningful variables and procedure names.

Here's my version of the same example procedure:

Code: Select all

Structure Something
  a.i
  b.i
  c.i
EndStructure

Procedure newSomething(*ptrThis.Integer)
  Protected *this.Something = AllocateMemory(SizeOf(Something))
  *ptrThis\i = *this
  *this\a = 1
  *this\b = 2
  *this\c = 3
EndProcedure
  

Define *this.Something

newSomething(@*this)

Debug *this\a
Debug *this\b
Debug *this\c
To show how this compares to what you suggested, here they are side by side:

Code: Select all

Structure Something                                                 
  a.i
  b.i
  c.i
EndStructure

Procedure newSomething(*ptrThis.Integer)                           Procedure That(&*This.Something)         
  Protected *this.Something = AllocateMemory(SizeOf(Something))      *This=AllocateMemory(SizeOf(Something))
  *ptrThis\i = *this                                                                           
  *this\a = 1                                                        *This\a=1                            
  *this\b = 2                                                        *This\b=2                            
  *this\c = 3                                                        *This\c=3                            
EndProcedure                                                       EndProcedure 
                                                                                     
                                                                                     
Define *this.Something                                             Define *This.Something                   
newSomething(@*this)                                               That(*This)                              
Debug *this\a                                                      Debug *This\a                            
Debug *this\b                                                      Debug *This\b          
Debug *this\c                                                      Debug *This\c
I count only one line of difference. You be the judge. I favor this method over the one tinman suggested because it doesn't require creating additional structures.
USCode wrote:Many folks don't want to deal directly with pointers and a simple pass by reference keyword would be much appreciated
Since performing these operations means you are working with pointers it wouldn't matter if you used "NotAPtr this.Something" instead of "*this.Something", because you have to remember where the values are being read and written to. As noted previously using an "&" in the definition of a procedure parameter is just as hard as using "@" in a procedure call. The person using it needs to know why they are using it.


- 1
It seems a suggestion for redundant functionality that is already well covered by "*" pointers and the "@" operator and wouldn't help anyone who is already confused about using pointers.

@Edit: added the word "help" to the last sentence, it had been omitted as an oversight.
Last edited by Demivec on Fri Apr 17, 2009 4:02 pm, edited 1 time in total.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

Mistrel wrote:
Kaeru Gaman wrote:*reads over it half a dozen times*
Pass by reference is basically the equivalent functionality of the "shared" keyword but the variable is passed as a parameter instead of being declared statically.

To be more specific, the variable passed by reference is available within the same scope of the function. It means you don't have to pass by-address and then peek/poke/structured pointer your values in.

It's a great convenience, I think. In my opinion it can make code that involves a lot of dynamic allocation and pointer-passing much easier to read and write.
I know what "pass byRef" means...

but I don't see any advantage in all the points here.
working with structured pointers make it ALWAYS clearly visible that you are handling a byRef Value and no local Variable....
it's the "style" of PureBasic, and it's ok as it is.


if one needs more conveniance, I would rather recommend and support a feature request for quick-and-easy stucture-field-autocomplete in the IDE...
oh... and have a nice day.
Post Reply