HighDots Forums  

Newbie Problem w/Return from a Function?

Javascript JavaScript language (comp.lang.javascript)


Discuss Newbie Problem w/Return from a Function? in the Javascript forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
scandal
 
Posts: n/a

Default Newbie Problem w/Return from a Function? - 07-03-2005 , 11:13 PM






I am a newbie, and after a long day of searching, reading, and trying
things, I cannot figure out what I am doing wrong. I know it's
something silly, but I could use some help:

Here's a simplified version of my code that apparently has the error in
it (an explanation of my problem follows):

<script type="text/javascript" >

var start_cell_no = horiz_endpoint(4);
alert ("result assigned to variable: " + start_cell_no);
alert("function result directly: " + horiz_endpoint(4));

function horiz_endpoint(last_cell_chked){
var cell_to_chk = last_cell_chked + 1;
if (cell_to_chk == 30){
javascript:alert ("right horizontal end is: " + last_cell_chked);
return last_cell_chked;
}
horiz_endpoint(cell_to_chk);
}
</script>

The code snippet correctly iterates until it triggers the function's if
statement. It prints the correct value for last_cell_chked. I should
then return that same value, but it doesn't. (Or, if it does, the
calling statements are somehow bunged up.) Both alert statements in the
main script say that the value returned is "undefined.

What am I doing that I am not supposed to be doing, or what tittle have
I omitted?

Thanks very much.

Reply With Quote
  #2  
Old   
Christopher J. Hahn
 
Posts: n/a

Default Re: Newbie Problem w/Return from a Function? - 07-03-2005 , 11:27 PM






scandal wrote:
Quote:
I am a newbie, and after a long day of searching, reading, and trying
things, I cannot figure out what I am doing wrong. I know it's
something silly, but I could use some help:

Here's a simplified version of my code that apparently has the error in
it (an explanation of my problem follows):

script type="text/javascript"

var start_cell_no = horiz_endpoint(4);
alert ("result assigned to variable: " + start_cell_no);
alert("function result directly: " + horiz_endpoint(4));

function horiz_endpoint(last_cell_chked){
var cell_to_chk = last_cell_chked + 1;
if (cell_to_chk == 30){
javascript:alert ("right horizontal end is: " + last_cell_chked);
return last_cell_chked;
}
horiz_endpoint(cell_to_chk);
}
/script

The code snippet correctly iterates until it triggers the function's if
statement. It prints the correct value for last_cell_chked. I should
then return that same value, but it doesn't. (Or, if it does, the
calling statements are somehow bunged up.) Both alert statements in the
main script say that the value returned is "undefined.

What am I doing that I am not supposed to be doing, or what tittle have
I omitted?

Thanks very much.
javascript:alert ("right horizontal end is: " + last_cell_chked)

Should be

alert("right horizontal end is: " + last_cell_chked)

But the logic problem is that you are recursing instead of looping, and
your recursed function calls are returning to the function that called
them, not to the 'main program'.

You can either rewrite it as a loop (I really think this is the best
solution) or change
horiz_endpoint(cell_to_chk);
}
to
return horiz_endpoint(cell_to_chk);
}

for a quick fix.



Reply With Quote
  #3  
Old   
RobG
 
Posts: n/a

Default Re: Newbie Problem w/Return from a Function? - 07-03-2005 , 11:34 PM



scandal wrote:
Quote:
I am a newbie, and after a long day of searching, reading, and trying
things, I cannot figure out what I am doing wrong. I know it's
something silly, but I could use some help:

Here's a simplified version of my code that apparently has the error in
it (an explanation of my problem follows):

script type="text/javascript"

var start_cell_no = horiz_endpoint(4);
alert ("result assigned to variable: " + start_cell_no);
alert("function result directly: " + horiz_endpoint(4));

function horiz_endpoint(last_cell_chked){
var cell_to_chk = last_cell_chked + 1;
if (cell_to_chk == 30){
javascript:alert ("right horizontal end is: " + last_cell_chked);
return last_cell_chked;
}
horiz_endpoint(cell_to_chk);
}
/script

The code snippet correctly iterates until it triggers the function's if
statement. It prints the correct value for last_cell_chked. I should
then return that same value, but it doesn't. (Or, if it does, the
calling statements are somehow bunged up.) Both alert statements in the
main script say that the value returned is "undefined.

What am I doing that I am not supposed to be doing, or what tittle have
I omitted?
You're using recursion when you should be using a conditional loop
(for, while, do, etc.). You also make use of the javascript pseudo-
protocol in a rather novel manner where it is not required.

The function does not appear to do anything useful, I hope the
following provides some assistance:

function horiz_endpoint( cell_to_chk ){

// While cell_to_check is less than 30, keep adding to it
while ( ++cell_to_chk < 30 ) {
// do something, or nothing...
}

alert('right horizontal end is: ' + cell_to_chk );
return cell_to_chk;
}


Quote:
Thanks very much.

--
Rob


Reply With Quote
  #4  
Old   
scandal
 
Posts: n/a

Default Re: Newbie Problem w/Return from a Function? - 07-04-2005 , 12:12 AM





Christopher J. Hahn wrote:

Quote:
scandal wrote:

I am a newbie, and after a long day of searching, reading, and trying
things, I cannot figure out what I am doing wrong. I know it's
something silly, but I could use some help:

Here's a simplified version of my code that apparently has the error in
it (an explanation of my problem follows):

script type="text/javascript"

var start_cell_no = horiz_endpoint(4);
alert ("result assigned to variable: " + start_cell_no);
alert("function result directly: " + horiz_endpoint(4));

function horiz_endpoint(last_cell_chked){
var cell_to_chk = last_cell_chked + 1;
if (cell_to_chk == 30){
javascript:alert ("right horizontal end is: " + last_cell_chked);
return last_cell_chked;
}
horiz_endpoint(cell_to_chk);
}
/script

The code snippet correctly iterates until it triggers the function's if
statement. It prints the correct value for last_cell_chked. It should
then return that same value, but it doesn't. (Or, if it does, the
calling statements are somehow bunged up.) Both alert statements in the
main script say that the value returned is "undefined.
[snip]
[snip]

Quote:
But the logic problem is that you are recursing instead of looping, and
your recursed function calls are returning to the function that called
them, not to the 'main program'.

You can either rewrite it as a loop (I really think this is the best
solution) or change
horiz_endpoint(cell_to_chk);
}
to
return horiz_endpoint(cell_to_chk);
}

for a quick fix.
Thanks for the quick response.

I have tried the last solution - keeping the recursion but having two
return statements - and it works. Do I understand this correctly?
Let's say it takes 3 iterations to meet the if condition. So, in call 1
the function hits the if statement, doesn't meet the condition, so it
"returns" by entering the next iteration. Let me call that call 2.
Again, it returns, calling itself - call 3. This time the if
conditional is satisfied, the script returns last_cell_chked to call 2,
but then what happens?

When I thought the original return (conditioned on the if) took it all
back to main, it made sense, but - as you have pointed out - that's not
the way it actually worked.

I don't think this works the way I understand perl working, but maybe I
have been operating with a misunderstanding for years and need to try it
in perl.

Why would you recommend a loop vs. a recursive solution? I thought loop
but cannot tell how many iterations I will need. Can one modify the
counter value in the body of a for loop without screwing things up?

Thanks again.


Reply With Quote
  #5  
Old   
scandal
 
Posts: n/a

Default Re: Newbie Problem w/Return from a Function? - 07-04-2005 , 01:09 AM





RobG wrote:

Quote:
scandal wrote:

I am a newbie, and after a long day of searching, reading, and trying
things, I cannot figure out what I am doing wrong. I know it's
something silly, but I could use some help:

Here's a simplified version of my code that apparently has the error
in it (an explanation of my problem follows):

script type="text/javascript"

var start_cell_no = horiz_endpoint(4);
alert ("result assigned to variable: " + start_cell_no);
alert("function result directly: " + horiz_endpoint(4));

function horiz_endpoint(last_cell_chked){
var cell_to_chk = last_cell_chked + 1;
if (cell_to_chk == 30){
javascript:alert ("right horizontal end is: " + last_cell_chked);
return last_cell_chked;
}
horiz_endpoint(cell_to_chk);
}
/script
[snip]

Quote:
You're using recursion when you should be using a conditional loop
(for, while, do, etc.). You also make use of the javascript pseudo-
protocol in a rather novel manner where it is not required.

The function does not appear to do anything useful, I hope the
following provides some assistance:

function horiz_endpoint( cell_to_chk ){

// While cell_to_check is less than 30, keep adding to it
while ( ++cell_to_chk < 30 ) {
// do something, or nothing...
}

alert('right horizontal end is: ' + cell_to_chk );
return cell_to_chk;
}
Thanks for the salient response. You're right: the code I posted REALLY
doesn't do anything useful. I was working my original code over to try
to get at the essence of my problem.

The real code, given any cell in an array arranged by rows and columns,
is supposed to return the ending cell and length of a horizontal line of
cells with matching contents. I chose a recursion over a loop because:
1) I don't know how long the line will be. A loop set up to iterate to
row length would work if I return when I reach a non-matching cell; 2) I
was initially lazy and thought recursion was simple. Then, of course, I
spent hours and hours trying to figure out why it didn't work.

Do you think a loop would be better, now that I (with help) have the
recursion working? All other critique is welcome, though it may be painful.

Here's the non-simplified version (still not incredibly useful!):

<script type="text/javascript" >

var cell_contents = [
0,0,0,0,0,
1,1,1,1,1,
1,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0];

var no_rows = 5;
var no_cols = 5;
var stack = 3;

function remove_stacks(cell_no){
var starting_cell = new cell(cell_no);
var endpoint_horiz_func = horiz_endpoint;
var count_horiz_func = count_horizontal;
var horiz_line = new line(starting_cell, endpoint_horiz_func,
count_horiz_func);
if (horiz_line.no_cells >= stack){
alert("found a stack: ends at "+horiz_line.endcell.index);
//do something here
}
return;
}
function line(one_point, endcell_method, countcell_method){
var point_col = one_point.col;
var point_index = one_point.index;
this.endcell = new cell(endcell_method(point_index, point_col));
this.no_cells = countcell_method(this.endcell.index, this.endcell.col, 0);
}
function cell(cell_no){
this.index = cell_no;
this.row = Math.floor(cell_no/no_cols);
this.col = cell_no -(Math.floor(cell_no/no_cols)*no_cols);
}
function horiz_endpoint(last_cell_chked, col){
var cell_to_chk = last_cell_chked + 1;
if (col + 1 >= no_cols || cell_contents[cell_to_chk] !=
cell_contents[last_cell_chked]){
javascript:alert ("right horizontal end is: " + last_cell_chked);
return last_cell_chked;
}
return horiz_endpoint(cell_to_chk, col + 1);
}

function count_horizontal(last_cell_chked, col, no_matched){
var cell_to_chk = last_cell_chked - 1;
if (col - 1 <= 0 || cell_contents[cell_to_chk] !=
cell_contents[last_cell_chked]){
javascript:alert ("left horizontal end is: " + last_cell_chked);
return last_cell_chked;
}
no_matched++;
return count_horizontal(cell_to_chk, col + 1, no_matched);
}

remove_stacks(6);

</script>



Reply With Quote
  #6  
Old   
RobG
 
Posts: n/a

Default Re: Newbie Problem w/Return from a Function? - 07-04-2005 , 02:35 AM



scandal wrote:
Quote:

RobG wrote:

scandal wrote:

I am a newbie, and after a long day of searching, reading, and trying
things, I cannot figure out what I am doing wrong. I know it's
something silly, but I could use some help:

Here's a simplified version of my code that apparently has the error
in it (an explanation of my problem follows):

script type="text/javascript"

var start_cell_no = horiz_endpoint(4);
alert ("result assigned to variable: " + start_cell_no);
alert("function result directly: " + horiz_endpoint(4));

function horiz_endpoint(last_cell_chked){
var cell_to_chk = last_cell_chked + 1;
if (cell_to_chk == 30){
javascript:alert ("right horizontal end is: " +
last_cell_chked);
return last_cell_chked;
}
horiz_endpoint(cell_to_chk);
}
/script


[snip]

You're using recursion when you should be using a conditional loop
(for, while, do, etc.). You also make use of the javascript pseudo-
protocol in a rather novel manner where it is not required.

The function does not appear to do anything useful, I hope the
following provides some assistance:

function horiz_endpoint( cell_to_chk ){

// While cell_to_check is less than 30, keep adding to it
while ( ++cell_to_chk < 30 ) {
// do something, or nothing...
}

alert('right horizontal end is: ' + cell_to_chk );
return cell_to_chk;
}


Thanks for the salient response. You're right: the code I posted REALLY
doesn't do anything useful. I was working my original code over to try
to get at the essence of my problem.

The real code, given any cell in an array arranged by rows and columns,
is supposed to return the ending cell and length of a horizontal line of
cells with matching contents.
What you seem to be attempting is looking for a row of a matrix where
all the elements are of the value you are searching with. But you are
using a one-dimensional array (a vector) not a matrix.

Matrices can be modeled in JavaScript using an array of arrays. In
your case, the equivalent 'cell_contents' object will be:

var cell_contents = [
[0,0,0,0,0], // row 0
[1,1,1,1,1], // row 1
[1,0,0,0,0], // row 2
[0,0,0,0,0], // row 3
[0,0,0,0,0] // row 4
];

That will explicitly put one array of 5 values into each 'row' of a
5 row 'matrix'.

The function below will return the index of the first row with a set of
matching values. Finding the last row is simpler, but there you go.
It makes the assumption that you will pass it a valid 2D matrix.

var cell_contents = [
[0,0,0,0,0], // row 0
[1,1,1,1,1], // row 1
[1,0,0,0,0], // row 2
[0,0,0,0,0], // row 3
[0,0,0,0,0] // row 4
];

function findRowOf( i, A ) {
var j=0, k;
var allMatch = false;

while ( !allMatch && 'undefined' != A[j] ) {
k = 0;
allMatch = true;
while ( allMatch && 'undefined' != typeof A[j][k] ) {
if ( i != A[j][k] ) allMatch = false;
k++;
}
j++;
}
return (allMatch)? j-1 : allMatch;
}

alert('Matching row? ' + findRowOf(1, cell_contents) );


If counting backward is OK (you'll get the last matching row, not the
first), then the following is more concise:


function findRowOf( i, A ) {
var k, j=A.length;
var allMatch = false;

while ( !allMatch && j-- ) {
k = A[j].length;
allMatch = true;
while ( allMatch && k-- ) {
if ( i != A[j][k] ) allMatch = false;
}
}
return (allMatch)? j : allMatch;
}



Quote:
I chose a recursion over a loop because:
1) I don't know how long the line will be. A loop set up to iterate to
row length would work if I return when I reach a non-matching cell; 2) I
Just set up the loop to continue to the end. When your condition is
met, return with the value. If it's never met, return with whatever you
want if it isn't met (false, null, 'no match', ...)

Quote:
was initially lazy and thought recursion was simple. Then, of course, I
spent hours and hours trying to figure out why it didn't work.
Recursion is simple, but your example seems far more complex than it
needs to be. If your data is structured in rows, use the structure to
help you out. Iterate over rows. As soon as a non-match is detected,
skip to the next row. If you get to the end of the row and all values
matched, then return that row index.

Recursion has two issues: it is a memory hog, and the number of
iterations seems to be limited to 1,000 (perhaps a lurking guru can say
why). A test case is below:

function countRecursion(i,n){
if ( i < n ) {
if ( ++i == n ) { return i };
return countRecursion( i, n );
}
}
function countLoop(i,n){
if ( i < n ) {
while ( ++i < n ) {}
}
return i;
}

var n=1000, t, j, k;

var s = new Date();
j = countRecursion(0, n)
var f = new Date();
t = f-s;

s = new Date();
k = countLoop(0, n)
f = new Date();

alert(
'recursion: ' + t + ' : ' + j
+ '\nloop: ' + (f-s) + ' : ' + k
);


On the other hand, the number of iterations of a loop is (generally)
only limited by your patience. :-)

Quote:
Do you think a loop would be better, now that I (with help) have the
recursion working? All other critique is welcome, though it may be
painful.
Yes.

[...]


--
Rob


Reply With Quote
  #7  
Old   
Christopher J. Hahn
 
Posts: n/a

Default Re: Newbie Problem w/Return from a Function? - 07-04-2005 , 02:58 AM



scandal wrote:
Quote:
Christopher J. Hahn wrote:

scandal wrote:

I am a newbie, and after a long day of searching, reading, and trying
things, I cannot figure out what I am doing wrong. I know it's
something silly, but I could use some help:

Here's a simplified version of my code that apparently has the error in
it (an explanation of my problem follows):

script type="text/javascript"

var start_cell_no = horiz_endpoint(4);
alert ("result assigned to variable: " + start_cell_no);
alert("function result directly: " + horiz_endpoint(4));

function horiz_endpoint(last_cell_chked){
var cell_to_chk = last_cell_chked + 1;
if (cell_to_chk == 30){
javascript:alert ("right horizontal end is: " + last_cell_chked);
return last_cell_chked;
}
horiz_endpoint(cell_to_chk);
}
/script

The code snippet correctly iterates until it triggers the function's if
statement. It prints the correct value for last_cell_chked. It should
then return that same value, but it doesn't. (Or, if it does, the
calling statements are somehow bunged up.) Both alert statements in the
main script say that the value returned is "undefined.

[snip]
[snip]

But the logic problem is that you are recursing instead of looping, and
your recursed function calls are returning to the function that called
them, not to the 'main program'.

You can either rewrite it as a loop (I really think this is the best
solution) or change
horiz_endpoint(cell_to_chk);
}
to
return horiz_endpoint(cell_to_chk);
}

for a quick fix.

Thanks for the quick response.

I have tried the last solution - keeping the recursion but having two
return statements - and it works. Do I understand this correctly?
Let's say it takes 3 iterations to meet the if condition. So, in call 1
the function hits the if statement, doesn't meet the condition, so it
"returns" by entering the next iteration. Let me call that call 2.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Therein lies the source of the confusion. It's not returning-- just
passing control to another function call. See below, as I think it sums
it up.

Quote:
Again, it returns, calling itself - call 3. This time the if
conditional is satisfied, the script returns last_cell_chked to call 2,
but then what happens?

When I thought the original return (conditioned on the if) took it all
back to main, it made sense, but - as you have pointed out - that's not
the way it actually worked.

I don't think this works the way I understand perl working, but maybe I
have been operating with a misunderstanding for years and need to try it
in perl.
I think the confusion stems from the fact that PERL automagically
returns the value of the last expression in the block, while most other
languages require an explicit return. The logic would have worked
perfectly in PERL because it does that extra bit of work for you,
however if you'd had any code after the function call (after the
condition is not met), it would have broken even in that most magical
of tongues.

JS only returns a value if you tell it to.

Quote:
Why would you recommend a loop vs. a recursive solution? I thought loop
but cannot tell how many iterations I will need. Can one modify the
counter value in the body of a for loop without screwing things up?
RobG got this for you already.

Quote:
Thanks again.
A pleasure!

(my original response was much longer and went on about stack frames
and all that jazz, but then I accidentally blew it away-- if this
doesn't clarify things for you, let me know and I'm more than happy to
try to reconstruct it)



Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.