HighDots Forums  

Returning multiple results from a subroutine ?

Javascript JavaScript language (comp.lang.javascript)


Discuss Returning multiple results from a subroutine ? in the Javascript forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Dr John Stockton
 
Posts: n/a

Default Returning multiple results from a subroutine ? - 09-22-2003 , 05:51 PM







What are the best ways of returning multiple results from a subroutine ?

I've been using
... return [a, b, c] }
which is inelegant.

I'm used to Pascal's
procedure X(const A, B : integer; var C, D : byte) ;
where A, B are inputs only, and C, D are in/out.

The needed parameters tend to be numbers, and don't need to be objects.

... return {aa:a, bb:b, cc:c} } // seems OK

but with that the parameter names aa, bb, cc are not visible in the
calling statement, which is a defect.

I'm specifically trying to extend, neaten, & improve <URL:http://www.mer
lyn.demon.co.uk/js-date5#DDTA>.

--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
<URL:http://jibbering.com/faq/> Jim Ley's FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> JS maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/JS/&c., FAQ topics, links.

Reply With Quote
  #2  
Old   
asdf asdf
 
Posts: n/a

Default Re: Returning multiple results from a subroutine ? - 09-23-2003 , 01:04 PM






You could pass in a function pointer to a callback.

You could implement your method as a mutator on a javascript class
(the new internal state would be your return values).

hope that helps,
Ron

Reply With Quote
  #3  
Old   
Lasse Reichstein Nielsen
 
Posts: n/a

Default Re: Returning multiple results from a subroutine ? - 09-23-2003 , 04:33 PM



b0b0b0b (AT) yahoo (DOT) com (asdf asdf) writes:

Quote:
You could pass in a function pointer to a callback.
Ah, Continuation Passing Style My first thought too, but not something
I would recommend in a language without tail-call optimization.

Quote:
You could implement your method as a mutator on a javascript class
(the new internal state would be your return values).
If you want to emulate call-by-name (the "var" parameter of Pascal or
&-parameter of C++), you can pass a return-object, and set the values
as propertie of it, instead of creating the object in the called
function. It is the closest to a Pascal "var"-parameter that I can
find.

I miss the tuples and simultaneous assignments of languages like SML
and Perl. There is no equivalent in Javascript. The closest would be
a returning an object and using a "with" statement.

/L
--
Lasse Reichstein Nielsen - lrn (AT) hotpop (DOT) com
Art D'HTML: <URL:http://www.infimum.dk/HTML/randomArtSplit.html>
'Faith without judgement merely degrades the spirit divine.'


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

Default Re: Returning multiple results from a subroutine ? - 09-23-2003 , 08:04 PM



It may be less elegant than what you have now, but you could put all
the numbers into an array. Then just pass a single variable (the array
name) in and out of the sub-routine and access the elements of the
array as required.

David

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

Default Re: Returning multiple results from a subroutine ? - 09-24-2003 , 12:48 AM



Lasse Reichstein Nielsen <lrn (AT) hotpop (DOT) com> wrote

Quote:
b0b0b0b (AT) yahoo (DOT) com (asdf asdf) writes:



I miss the tuples and simultaneous assignments of languages like SML
and Perl. There is no equivalent in Javascript. The closest would be
a returning an object and using a "with" statement.

Or, at the risk of offending those who so far only moderately despise
"with", and highly despise "eval", you could alternatively re-manifest
the return object properties into caller variables by:

for (var j in retObj) eval(j +"=retObj['"+j+"']");

which might come a little closer to call by name than the use of
"with". That's in the vein of a somewhat neutral observation, as
opposed to a recommendation, however.

(By the way, I fully concur with the attempt to stamp out the evil of
[completely unnecessary use of] eval. Nonetheless, I have run into
cases where only the name of a variable is known, and in the absence
of an available reference, have taken the reasonable course and
eval'ed in order to assign/retrieve a value. If there's a good
alternative, the doh'lt is yet to discover it.)

../rh

Quote:
/L

Reply With Quote
  #6  
Old   
Douglas Crockford
 
Posts: n/a

Default Re: Returning multiple results from a subroutine ? - 09-24-2003 , 01:03 AM



Quote:
(By the way, I fully concur with the attempt to stamp out the evil of
[completely unnecessary use of] eval. Nonetheless, I have run into
cases where only the name of a variable is known, and in the absence
of an available reference, have taken the reasonable course and
eval'ed in order to assign/retrieve a value. If there's a good
alternative, the doh'lt is yet to discover it.)
var global = this; // This is more portable than relying on 'window'.
....
var variable_name = "foo";
var value = global[variable_name];

http://www.crockford.com/javascript/remedial.html



Reply With Quote
  #7  
Old   
Lasse Reichstein Nielsen
 
Posts: n/a

Default Re: Returning multiple results from a subroutine ? - 09-24-2003 , 05:45 AM



codeHanger (AT) yahoo (DOT) ca (rh) writes:

Quote:
Or, at the risk of offending those who so far only moderately despise
"with", and highly despise "eval",
That would be me

Quote:
you could alternatively re-manifest the return object properties
into caller variables by:

for (var j in retObj) eval(j +"=retObj['"+j+"']");
This differs from using "with" in two ways:

- You only get the values of the enumerable properties of retObj.
Using "with" makes all the properties visible. That is not so much of
a difference, since the non-enumerable properties of a new object (the
ones in Object.prototype) are already visible as properties of the
global object.

- It assigns the values to local variables if they exist, but those
properties that don't have a local variable of the same name are
created as global variables. With a "with", they are all made local
variables, but will shadow preexisting local variables of the same
name.

This is actually a use for eval that I can't find a way around:
setting the value of a local variable given its name as a string.
It is also bad coding practice. Local variables should be free to
be renamed without changing the how the program works, but this
code will let a function from anywhere in the program change a local
variable by name. I recommend against it.

I would recommend returning an array and have the caller decide which
variables to assign to, or returning an object, and letting the caller
decide how to access the properties.

Quote:
which might come a little closer to call by name than the use of
"with".
Maybe a little closer, but it is not call-by-name. It is
call-by-copy-restore, but I think that is the best we can get anyway.

Quote:
That's in the vein of a somewhat neutral observation, as
opposed to a recommendation, however.


Quote:
(By the way, I fully concur with the attempt to stamp out the evil of
[completely unnecessary use of] eval. Nonetheless, I have run into
cases where only the name of a variable is known, and in the absence
of an available reference, have taken the reasonable course and
eval'ed in order to assign/retrieve a value. If there's a good
alternative, the doh'lt is yet to discover it.)
If the variable is a local variable, then I can't see another way,
since we don't have a reference to the activation object. I highly
recommend not to throw around the names of local variables, though.
Make the global if someone outside of the scope needs to have access
to them.

/L
--
Lasse Reichstein Nielsen - lrn (AT) hotpop (DOT) com
Art D'HTML: <URL:http://www.infimum.dk/HTML/randomArtSplit.html>
'Faith without judgement merely degrades the spirit divine.'


Reply With Quote
  #8  
Old   
Dr John Stockton
 
Posts: n/a

Default Re: Returning multiple results from a subroutine ? - 09-24-2003 , 10:53 AM



JRS: In article <65jj6vgn.fsf (AT) hotpop (DOT) com>, seen in
news:comp.lang.javascript, Lasse Reichstein Nielsen <lrn (AT) hotpop (DOT) com>
posted at Tue, 23 Sep 2003 23:33:44 :-
Quote:
b0b0b0b (AT) yahoo (DOT) com (asdf asdf) writes:

You could implement your method as a mutator on a javascript class
(the new internal state would be your return values).

If you want to emulate call-by-name (the "var" parameter of Pascal or
&-parameter of C++), you can pass a return-object, and set the values
as propertie of it, instead of creating the object in the called
function. It is the closest to a Pascal "var"-parameter that I can
find.

I miss the tuples and simultaneous assignments of languages like SML
and Perl. There is no equivalent in Javascript. The closest would be
a returning an object and using a "with" statement.
Those do not, AFAICS, have the property that the names of the output
items are visible in the calling statement, which is a pity at least to
one of my habits.

Also there is not the de-coupling between internal and external names,
as there is in function Neg(x) { return -x } ... z = Neg(y) .

So ISTM that either I force the parameters to be Objects, gaining
visibility; or, since this is all about a date, make the outputs
parameters of a Date Object, albeit one that does not really mean the
time_t of its valueOf().

Thanks to all.

--
© John Stockton, Surrey UK. ????@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
MAIL: not reply@, spam@, or? jrs@; try as newsYYMM@ e.g. YYMM=0309 updated.
Do not use it anywhere except in sending mail to me; do not publish it.


Reply With Quote
  #9  
Old   
rh
 
Posts: n/a

Default Re: Returning multiple results from a subroutine ? - 09-24-2003 , 02:17 PM



Lasse Reichstein Nielsen <lrn (AT) hotpop (DOT) com> wrote

Quote:
codeHanger (AT) yahoo (DOT) ca (rh) writes:

Or, at the risk of offending those who so far only moderately despise
"with", and highly despise "eval",

That would be me
And me
Quote:
you could alternatively re-manifest the return object properties
into caller variables by:

for (var j in retObj) eval(j +"=retObj['"+j+"']");

This differs from using "with" in two ways:

- You only get the values of the enumerable properties of retObj.
...
While that may be a difference in the use of "with", my assumption was
that retObj would be generated as an object literal as the return
expression in the called function. As such, there wouldn't be any
non-enumerable properties.

Quote:
- It assigns the values to local variables if they exist, but those
properties that don't have a local variable of the same name are
created as global variables. With a "with", they are all made local
variables, but will shadow preexisting local variables of the same
name.

See below regarding restriction.

Quote:
This is actually a use for eval that I can't find a way around:
setting the value of a local variable given its name as a string.
Thanks for confirming.

Quote:
It is also bad coding practice. Local variables should be free to
be renamed without changing the how the program works, but this
code will let a function from anywhere in the program change a local
variable by name. I recommend against it.
The eval is in the calling function, so the only functions that could
change local variables within are those where there is an explicit
intention to allow it. It would be trivial to restrict the variables
in the caller that would be open to change by the callee (by evaling
on the restricted set, as opposed to the property names provided by
retObj). If you don't want to trust, you don't have to.

Quote:
I would recommend returning an array and have the caller decide which
variables to assign to, or returning an object, and letting the caller
decide how to access the properties.

I tend to use an array if there are two or three return values. More
than that, I create an object literal and access the properties.

Quote:
which might come a little closer to call by name than the use of
"with".

Maybe a little closer, but it is not call-by-name. It is
call-by-copy-restore, but I think that is the best we can get anyway.

That's in the vein of a somewhat neutral observation, as
opposed to a recommendation, however.




Quote:
If the variable is a local variable, then I can't see another way,
since we don't have a reference to the activation object. I highly
recommend not to throw around the names of local variables, though.
Make the global if someone outside of the scope needs to have access
to them.
As pointed out above, you don't really have to "throw around the
names". I hold a similar aversion to putting things into the global
namespace -- seems to me there's already too much potential for name
conflict and side-effects there.

Just trying to hold your feet to the fire a bit here.

../rh

Quote:
/L

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.