Page 1 of 1

Sub return

Posted: 02 June 2009, 5:49 AM
by laszlo
Hello!

I'm new to ZBasic and I stumbled into some difficulties. How do I make my subs return a value? Can I return an array? I tried with the command return (as in java), but got error.

This is what I'd like:

Code: Select all

Dim a(1 to 5) as Bit
Dim b(1 to 5) as Bit
Dim c(1 to 5) as Bit

Dim i as Byte = 1
For i = 1 to 5
   a(i) = CBit(CInt(Fix(Rnd())))
   b(i) = CBit(CInt(Fix(Rnd())))
Next i

' c(1 to 5) = big(a, b)

i = 1
For i = 1 to 5
   Console.Write(CStr(c(i)))
Next i



Sub big(ByRef a() as Bit, ByRef b() as Bit)
   Dim c(1 to 5) as Bit
   Dim i as Byte = 1
   
   For i = 1 to 5
	  If a&#40;i&#41; < b&#40;i&#41; Then
		 c&#40;i&#41; = b&#40;i&#41;
	  Else
		 c&#40;i&#41; = a&#40;i&#41;
		End If
   Next i

'  Return c
End Sub
   
The commented parts doesn't work.
I know that functions return values, but I haven't been able to return arrays.

My application is actually a simple genetic algorithm to calculate function maximum/minimum. I can post it when I'm done.

Posted: 02 June 2009, 6:33 AM
by mikep
Functions can only return "scalar types" such as an Integer, Unsigned Long and String. String could be considered as an array of bytes but special provision is made for this type (as is done in many programming languages).

To return a value, you use the name of the function as the return variaible e.g.

Code: Select all

Public Function Cubed&#40;x as Single&#41; as Single
    Cubed = x * x * x
End Function
To return an array, you need to pass it in as a ByRef parameter to the subroutine or function e.g.

Code: Select all

Sub big&#40;ByRef a&#40;&#41; as Bit, ByRef b&#40;&#41; as Bit, ByRef c&#40;&#41; as Bit&#41;
End Sub
As a comment on your code, there are faster ways to generate 10 random bits without calling the random number generator 10 times. For example you could multiply the generated number by 1024.0 and then extract the 10 bits from the resulting integer that is between 0 and 1023.

Posted: 02 June 2009, 6:43 AM
by laszlo
Thanks a lot for the quick reply! I'll try to work around the problem.

Re: Sub return

Posted: 02 June 2009, 8:32 AM
by dkinzer
laszlo wrote:I tried with the command return (as in java), but got error.
This issue arises because of the inherent difference in the design of Basic as compared to some other languages like C, C++, Java, etc. In the latter group, all procedures are functions - there are no subroutines. To get the behavior of a subroutine in these languages you simply define the procedure to be of type void meaning that it doesn't return anything. In Basic, a Subroutine is used for procedures that don't return a value and a Function is used for those that do.

As Mike pointed out, every function has an associated return value variable whose name is the same as the function name. The return value variable can be used anywhere that a normal variable can be used. To set the return value, you simply assign to the return value variable. You can assign a value to the return value variable as many time as you wish with in the function; the last value assigned will be the value that is returned. If you don't assign a value to the return value variable, the return value will be undefined.

Generally speaking, the ZBasic compiler will generate a warning if it detects that there is at least one path through the function that fails to set the return value variable. It is recommended to unconditionally assign a default return value (which you determine) to the return value variable early in the function. Thereafter, the code will only need to assign a return value in cases where it is different than the default value.

As for functions returning an array, this capability is generally not implemented in languages unless they have automatic garbage collection - Basic, C and C++ do not, Java does. As Mike mentioned, ZBasic supports functions returning a one value of a fundamental type (Byte, Integer, Single, etc.). However, it also supports returning a single value of String and structure types as special cases.

As with many other languages (including C and C++), multiple return values and arrays are implemented by passing a reference to variables/arrays allowing the function to modify them.

It is possible to design a function in ZBasic to return an UnsignedInteger value that is the address of a block of allocated memory containing an array, effectively returning an array. The caller is responsible for deallocating the memory block when it is no longer needed. This is an advanced technique that must be used carefully and it is recommended only for situations in which there are no other viable solutions.

Posted: 04 June 2009, 6:12 AM
by laszlo
Thank you for the comprehensive explanation. I found a way to work around it, by modifying an array defined outside the subroutine instead of trying to return it. Thanks for your time!