 |
 |

04-29-2011, 09:31 PM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
understanding function
|
I'm trying to learn functions, but having a bit of trouble with the return value.
Code:
Module modSquareInteger
Sub Main()
Dim i As Integer ' counter
' square numbers from 1 to 10
For i = 1 To 10
Console.WriteLine(i & vbTab & Square(i))
Next
End Sub ' Main
' Function Square is executed
' only when the function is explicitly called.
Function Square(ByVal y As Integer) As Integer
Return y ^ 2
End Function ' Square
End Module ' modSquareInteger
I see that the function return Y squared to this line
Code:
Console.WriteLine(i & vbTab & Square(i))
but where exactly does it return it, and why, and how do I know this from the code that's written?
Now I can't seem to figure out where Y is declared, and what it's value is...is it declared within the functions parenthesis, with the value of 0?
|
|

04-30-2011, 04:52 AM
|
 |
Ultimate Contributor
Retired Leader * Expert *
|
|
Join Date: Mar 2004
Location: Beaverton, OR
Posts: 1,874
|
|
The Y value is declared as the entry argument to the function routine. This is a variable available within the function whilst the function executes. Upon completion of the function the function return value is established with the Return statement and then Y ceases to exist. The return value is then brought back to the invoking program and plugged into the context of where the function was called. (In the case of your example the return value is concatenated into the argument list for the WriteLine method.
If you wanted to actually see the result of the function or be able to use it for more than one thing you could assign it to a variable:
Code:
Dim I as Integer
Dim Sq as Integer
I = 5
Sq = Square(I)
In the above the return value is brought to the right hand side of the = sign and then assigned to the variable Sq. In the following example the return values of two different invocations of the function are added together and then assigned to the variable:
Code:
Dim A as Integer
Dim SumSq as Integer
A = 5
SumSq = Square(A) + Square(3)
Here I would hope to see a result with SumSq being set equal to 25+9=34. Hope that little dialog helps your understanding.
Michael Karas
|
|

04-30-2011, 09:49 AM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
|
so in the example of my first post Y takes on the value of I each time?
|
|

04-30-2011, 10:02 AM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
|
let see if I got this right. Y takes on it's value from I..
the return value of Y^2 goes into I again?
that's something I don't understand how does a function know where to return a value? I know it goes back to the caller but there doesn't seem to be any direct method of know where in the caller it goes back to..at least not for me at the moment.
|
|

04-30-2011, 10:05 AM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
|
no no..never mind. I get it...it goes back to I where it was called. sorry, wasn't following the parameter list thing...so I see how it works now..
I goes to Y, and then back to I haha.
each time the loop iterates it gets a new value for I..
|
|

04-30-2011, 10:07 AM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
|
so the return value is always returned to the corresponding argument in the parameter list of it's caller?
|
Last edited by NewVBProgrammer; 04-30-2011 at 10:13 AM.
|

04-30-2011, 03:14 PM
|
 |
Ultimate Contributor
Retired Leader * Expert *
|
|
Join Date: Mar 2004
Location: Beaverton, OR
Posts: 1,874
|
|
|
Nope. The parameter list of a function like you had does NOT pass back the value in one of the entry argument variables.
The return value is simply captured into some transient storage allocated by the compiler/interpreter to be used back at the point of invocation. Depending upon context the return value may not even be used. The transient storage is often a machine register or set of registers that hold the value till needed. Note that the actual implementation of how the function return value transits back to the point of invocation is usually hidden from the high level language programmer and of no real concern.
Think of the process of using a calculator to balance your checkbook. Your brain is used to transport the values to be subtracted from the checkbook over to the keys in the calculator -- a process akin to the parameter calling conventions of invoking the function call. Then the calculator does its work through some work -- just like the function call being executed. Finallly the result is seen in the calculator display. Such result is placed into your brain and taken back to be written into the next line of the check book register. Your brain is acting as the transient storage for the return value from the calculator function. In the mean time the calculator has been shut off leaving no connection between what it did and the result back in the check book.
Michael Karas
|
|

04-30-2011, 03:37 PM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
|
If the value isn't returned to the calling line how is the answer displayed in the console write line?
|
|

04-30-2011, 07:10 PM
|
 |
Fabulous Florist
Forum Leader * Guru *
|
|
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,416
|
|
Magic. No, really.
I could discuss exactly how the mechanism works, but unless you immediately know what I mean when I say "MSIL is a stack-based assembly-like language with heap storage for local variables" then it'll waste our time.
You could also ask how the compiler knows how to do the right thing in this code:
Code:
Dim x As Integer = 3
Dim result As Integer = x + 1
It's clear what happens. First, the compiler makes an Integer called x and stores 3 in it. Then it has to add x + 1, so it fetches the value (3) and adds 3 + 1, then stores it in an integer called result.
What if there's a function?
Code:
Dim result As Integer = GetX() + 1
It's no different. The compiler knows it needs to add two numbers. GetX() is an integer function, so the compiler executes it. It returns 3, so the compiler adds 3 + 1 and stores that.
If I gave you the formula X + Y = Z, then told you X=1 and Y=2, how would you tell me what Z is? You'd substitute 1 and 2 for X and Y, then add 1 and 2, and know the result is 3. What if I gave you f(X) + f(Y) = Z and told you f(x) = x + 1, X = 1, and Y = 2? Well, f(X) would be f(1) = 1 + 1 = 2, f(Y) would be f(2) = 2 + 1 = 3, and 2 + 3 = 5.
The real answer takes a page to describe and involves code like this:
Code:
PUSH 3
PUSH 4
CALL CalculateTotal
PUSH 3.99
MULTIPLY
SET_LOCAL 0
...
Hard to stomach. Hard to explain. You don't need to know your code this intimately to write it. Treat it like algebra and it just works.
|
|

04-30-2011, 09:02 PM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
|
does it actually return y^2 anywhere into the program to get the next calculation to display? I guess that's what's confusing me.
|
|

04-30-2011, 09:10 PM
|
 |
Fabulous Florist
Forum Leader * Guru *
|
|
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,416
|
|
As far as you need to be concerned, y^2 is not returned anywhere you can touch it.
If it's a result you'd like to use later without calling the function again, you must explicitly store it in a variable. Your example's a little weird for that, but it'd look like this:
Code:
Dim storedResult As Integer = Square(3)
Console.WriteLine("Result: " & storedResult.ToString())
|
|

05-01-2011, 05:55 AM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
but that's not my question. I'm trying to understand the basics of how this function works, not where invisible numbers go, lol.
how does it display the answer..I see how it displays the number it wants to square I that's easy
I comes from here.
gets displayed here.
Code:
Console.WriteLine(i
right after that the function gets called to do the math here.
Code:
Function Square(ByVal y As Integer) As Integer
Return y ^ 2
End Function
but the actual program displays the number that gets squared, and the square result in the output...how?
lol,
see what I mean...
|
|

05-01-2011, 08:00 AM
|
 |
Fabulous Florist
Forum Leader * Guru *
|
|
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,416
|
|
Well then, I guess you want the really detailed answer. Sometimes I think you should be satisfied with "magic". Do you need to know the chemical reaction that occurs when gasoline combusts to drive a car?
MSIL is a stack-based assembly language with an indexed local storage space available. Since I don't fancy a full explanation, here's a description of a few pseudo-opcodes I'm going to use: - PUSH puts an element on the stack.
- SET_LOCAL X stores the top element of the stack in the local storage space at index X.
- GET_LOCAL X pushes the value at local storage space X on the top of the stack.
- CALL jumps to the location indicated, executes that code, and returns to the next line when...
- RETURN indicates the code jumped to by a CALL is over.
I'll represent the stack with curly brackets; { 3, 4 } means the stack has two elements with 3 on top and 4 on the bottom.
Let's start simple. How would this snippet get turned in to IL?
Code:
Dim result As Integer = 3 + 4
First, variable storage has to be created. For simplicity we'll assume we're always in some sub or function; setting class-level fields is a little different. So result would be some local variable, probably at index 0. Here's the annotated IL:
Code:
PUSH 3
PUSH 4 | Stack is { 4, 3 }
ADD | Adds the top 2 elements of the stack and pushes the result
| Stack is { 7 }
SET_LOCAL 0 | Sets result to 7; stack is { }
ADD is an opcode that requires arguments. Its convention is to expect the top 2 items of the stack to be its operands. It pops them, adds them, then pushes them on the stack.
Function calls work like this as well. Any parameters they take are expected to be on the stack in a specific order. The function must pop all of its parameters off of the stack. Before it uses RETURN, a function is expected to push its return value onto the stack.
So let's say we wrote a cash register for a shoe store and wanted to write a GetTotal() function:
Code:
Function GetTotal(ByVal shoes As Integer, ByVal socks As Integer) As Double
Dim shoeTotal As Double = shoes * 10.00
Dim socksTotal As Double = socks * 1.00
Return shoeTotal + socksTotal
End Function
Here's what the (unoptimized) IL could look like for GetTotal(2, 3):
Code:
' Get parameters
SET_LOCAL 0
SET_LOCAL 1
' Dim shoeTotal As Double = shoes * 10.00
PUSH 10 | { 10 }
GET_LOCAL 0 | { 2, 10 }
MULTIPLY | { 20 }
SET_LOCAL 2
' Dim socksTotal As Double = socks * 1.00
PUSH 1
GET_LOCAL 1
MULTIPLY
SET_LOCAL 3
' Return shoeTotal + socksTotal
GET_LOCAL 2 | { 20 }
GET_LOCAL 3 | { 3, 20 }
ADD | { 23 }
RETURN
Just like I said, it expects its parameters to be on the stack and the first thing it does is store them. After it's done executing, it pushes its return value onto the stack and calls RETURN. What would code that uses this look like?
Code:
Console.WriteLine("Your total is: " & GetTotal(2, 3))
Console.WriteLine() itself is a sub. So we have to push its parameters onto the stack first. The IL could look like this:
Code:
PUSH 3 | { 3 }
PUSH 2 | { 2, 3 }
CALL GetTotal | { 23 }
CALL Integer.ToString | { "23" }
PUSH "Your total..." | { "Your...", 23 }
CALL String.op_Concat | { "Your total is 23" }
CALL Console.WriteLine
The compiler realizes it has to call the function first, so it pushes the two parameters. Then it calls GetTotal(). This leaves the result on the stack. Next, the compiler has to concatenate "Your total is " with the number 23. It can only do this with two strings, so it converts 23 to a string by calling Integer.ToString() on it. Next, it pushes the "Your total is " part on the stack. String.op_Concat pops the two strings, concatenates them, and pushes the result onto the stack. Finally, Console.WriteLine prints the simgle string.
So there's your answer: the result is on the stack when the function returns. You can't touch this stack; only the compiler or programs written directly in IL are allowed to manipulate the stack. Again, I want to stress this is too much knowledge for any given task; it's not your job to think about IL when you're writing VB. The entire point of using a high-level language is to avoid this kind of tedium. If you *still* want to learn more, you are on the wrong forum and I suggest you turn to other sources.
If you can use variables, functions shouldn't be so confusing. A function is a variable that calculates its result.
|
|

05-01-2011, 08:31 AM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
I'm not asking what is done as it goes through the compiler.....
take this for example
I'm asking how is C displayed on the screen when there is no code telling it to be..
in the above function I don't understand how the answer is displayed...I can't see the code that tells it to be. I only see the code that shows the number that will be squared in the output....not the answer too..
to me the above function works like this
Code:
a + b = C
return C
display a + b like this
a b [yet somehow c gets displayed here too]
|
Last edited by NewVBProgrammer; 05-01-2011 at 08:40 AM.
|

05-01-2011, 09:28 AM
|
|
Junior Contributor
|
|
Join Date: Jul 2006
Posts: 354
|
|
|
I might know the answer to that one...
a + b = C
but in code it would be represeted as
C = a + b
Therefore when you return C, you get the sum of a + b
|
|

05-01-2011, 12:16 PM
|
 |
Fabulous Florist
Forum Leader * Guru *
|
|
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,416
|
|
Nothing gets displayed in your #14 snippet because you don't ask the program to display anything.
Going back to #1, you call Console.WriteLine(). This displays its string parameter to the console. First, you form a string by joining the variable i, a tab, and the result of calling Square() on the variable i. That string is passed to Console.WriteLine. That's what gets displayed. You aren't supposed to (nor do you need to) care how that string gets from WriteLine() to the screen; if you had to worry about that you'd never get anything done. Suffice to say there's some system call somewhere that says "Consider the address in this CPU register to point to a string in memory; fetch that string and display its characters on the console window." Again, it's worrying about the chemical reaction of gasoline combustion as if it matters for driving a car.
I'm really struggling to understand what you don't get. Out of this list, are there any that you don't understand how they work? I'll try and explain them. Pick out which ones are the least clear.
1.
Code:
Console.Writeline("I am a string")
This should be obvious. The string's right there.
2.
Code:
Console.WriteLine(1234)
1234 is an integer; WriteLine() converts it to a string in code you can't see (or maybe the compiler does it.)
3.
Code:
Console.WriteLine(1234.ToString() & "I am a string")
The & joins the two strings to form one string. It's stored temporarily. The compiler redoes this more like so:
Code:
Dim temp As String = 1234.ToString() & "I am a string"
Console.WriteLine(temp)
But this is all imaginary! You can't use that temporary variable, don't go looking for it.
4.
Code:
Dim message As String = "I am a string"
Console.WriteLine(message)
This is analogous to #1.
5.
Code:
Console.WriteLine(GetSomeString())
GetSomeString() is a function that returns a string. Again, you can pretend like the compiler rewrites the code for you:
Code:
Dim temp As String = GetSomeString()
MessageBox.Show(temp)
If you're still unclear, I don't know what to tell you. If it's between parenthesis, the compiler evaluates it first. So a function call in a parameter list gets replaced by its return value before the function is invoked.
|
|

05-01-2011, 12:29 PM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
I found what I was looking for. I just needed to think about it a little more I think...
that snippet in the writeline statement displays the answer returned by the function...how to function knows to return this answer, and what not isn't how deep i was wanting to go, i just wanted to know from within the code where it was told to be displayed...
I have another question now though. lol.
does the function not retain any values from it's first number to square to it's second, and so on?
the function 'clears' itself for each operation it does?
|
|

05-01-2011, 12:37 PM
|
 |
Fabulous Florist
Forum Leader * Guru *
|
|
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,416
|
|
|
Yes. Each time you call the function, it's as if it was the first time. There's a weird concept called "static local variables" that can be used to give a function a form of memory, but I've never really felt like it was a good feature. No good reason, just superstition.
|
|

05-01-2011, 12:47 PM
|
|
Centurion
|
|
Join Date: Jul 2010
Location: Grand Manan
Posts: 163
|
|
|
okay, I read somewhere that there was something that retains value from each time it was called, is it a sub?
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|
|
|
|
 |
|