Returning multiple results from a subroutine ?

Discussion in 'Javascript' started by Dr John Stockton, Sep 22, 2003.

  1. 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.
     
    Dr John Stockton, Sep 22, 2003
    #1
    1. Advertising

  2. Dr John Stockton

    David Guest

    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
     
    David, Sep 24, 2003
    #2
    1. Advertising

  3. Dr John Stockton

    rh Guest

    Lasse Reichstein Nielsen <> wrote in message news:<>...
    > (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

    > /L
     
    rh, Sep 24, 2003
    #3
  4. > (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
     
    Douglas Crockford, Sep 24, 2003
    #4
  5. (rh) writes:

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


    That would be me :)

    > 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.

    > 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.


    :)

    > (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 -
    Art D'HTML: <URL:http://www.infimum.dk/HTML/randomArtSplit.html>
    'Faith without judgement merely degrades the spirit divine.'
     
    Lasse Reichstein Nielsen, Sep 24, 2003
    #5
  6. JRS: In article <>, seen in
    news:comp.lang.javascript, Lasse Reichstein Nielsen <>
    posted at Tue, 23 Sep 2003 23:33:44 :-
    > (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.
     
    Dr John Stockton, Sep 24, 2003
    #6
  7. Dr John Stockton

    rh Guest

    Lasse Reichstein Nielsen <> wrote in message news:<>...
    > (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 :)
    >
    > > 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.

    > - 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.

    > 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.

    > 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.

    >
    > 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.

    > > 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.

    >
    > :)


    :)

    > 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

    >
    > /L
     
    rh, Sep 24, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Biranchi Narayan Panda
    Replies:
    0
    Views:
    578
    Biranchi Narayan Panda
    Feb 21, 2010
  2. john smith
    Replies:
    0
    Views:
    113
    john smith
    Mar 14, 2005
  3. Kirk Is
    Replies:
    5
    Views:
    117
    gnari
    Nov 26, 2004
  4. king
    Replies:
    5
    Views:
    210
  5. Alex van der Spek

    ctypes: returning an array from a subroutine

    Alex van der Spek, Apr 20, 2014, in forum: Python
    Replies:
    1
    Views:
    70
    Alex van der Spek
    Apr 20, 2014
Loading...

Share This Page