Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
But how could you handle the simple case of assigning the return value to a variable?

The keyword was "subdivision". When the context cannot be broken down to a string or numeric context as in the case of assignment to a variable, then the context would be returned as simply 'SCALAR'. If the context can be further broken down, then that context would also be indicated. I haven't thought through how this would be done, but one way might be to return 'SCALAR/STRING' and 'SCALAR/NUMERIC' respectively in the case of your two if statements. Instead of coding if( want() eq 'SCALAR' ) {

You would code if( want() =~ /^SCALAR/ ) { if you were only interested in determining scalar context. Integer and real contexts could be a supplement to that.

Alternatively, use a parameter to want() if( want( 'SCALAR' ) ) { would return true if the context was scalar string, scalar numeric, scalar numeric real or scalar numeric integer, but if( want( 'INTEGER' ) ) { would only return true if the return was being used in an inherently integer context like an array indices, range boundary or as an argument to a function that had been indicated as an integer (using the much improved prototyping facility:).

The main reason I thought of for wanting to distinguish between a list context and an array context, is the following

sub dostuff { my @array; # doing stuff building @array return @array; } ... my @returned = dostuff();

In the above scenario, we have a lexically local @array built up within the sub. When it comes time to return this to the caller, the array is flattened to a list, which currently appears to consume some extra memory over the array itself. On the basis of experiment, this appears to be less than the full size of the array, but is still a fairly substantial chunk of memory if the array is large. This list is then assigned to the array in the outer code consuming another large chunk of ram.

Crude measurements indicate that the total memory allocated by the simple act of returning an array through a list to another array is close to 3 times the original size of the array. For small arrays, not a problem, but for large ones this is expensive.

Yes, you can return a reference to the array, but the extra level of indirection involved can be a PITA, especially if the elements of the array are themselves compound structures.

My thinking is that if the programmer could determine that the destination is an array, then he might also be given access to an alias to that destination array and assign his return values directly to it.

sub DoSomething { my @array; alias( @array ) if want( 'ARRAY' ); #Do Stuff Directly to the destination array return; } ... my @returned = DoSomething();

This would effectively use the same mechanism as for loops do now.

If the results of the sub were being used in a list context, being pushed onto an array or printed in the calling code and the algorithm of the sub permits, then it can sometimes make sense not to acumulate the data into an array internally, but rather simple build and return a list.

sub DoStuff { die 'Nothing to do in a void context' if want( 'VOID' ); if( want( 'LIST' ) ) { return map{ # Do stuff to generate the list } ...; } my @array; alias( @array ) if want( 'ARRAY' ); push @array, $stuff for ....; return \@array if want( 'ARRAY/REF' ); # The callers array has been filled directly # If we were called in an array context. return; }

LW and TheDamian are probably way ahead of me on this, and it is possible that some of the benefits of this type of optimisation can be achieved transparently by comterpreter, but I think that there are cases were it would be useful for the programmer to have this level of control.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
Hooray!
Wanted!


In reply to Re: Re: Re: What should be returned in scalar context? by BrowserUk
in thread What should be returned in scalar context? by tilly

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (7)
As of 2024-04-19 08:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found