www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Nested functions return from parent functions

reply "Charlie" <charles jwavro.com> writes:
Sometimes goto is still the best solution for large functions with many
control paths, where an error action needs to be taken, then return from the
function. If we had something like


int myLargeFunction ()
{

    void onError(char [] x )
    {
        writefln("Error : %s,x );
        super.return -1;

    }

}

It might alleviate the need for goto altogether ?  What do yall think.

Charlie
Apr 21 2005
next sibling parent Sean Kelly <sean f4.ca> writes:
In article <d48n04$dur$1 digitaldaemon.com>, Charlie says...
Sometimes goto is still the best solution for large functions with many
control paths, where an error action needs to be taken, then return from the
function. If we had something like

int myLargeFunction ()
{

    void onError(char [] x )
    {
        writefln("Error : %s,x );
        super.return -1;

    }

}

It might alleviate the need for goto altogether ?  What do yall think.

This feature would eliminate one advantage that C macros still have over inner functions. I would love this. My unFormat implementation had to use exceptions for this sort of flow control. Sean
Apr 21 2005
prev sibling parent reply pragma <pragma_member pathlink.com> writes:
In article <d48n04$dur$1 digitaldaemon.com>, Charlie says...
Sometimes goto is still the best solution for large functions with many
control paths, where an error action needs to be taken, then return from the
function. If we had something like


int myLargeFunction ()
{

    void onError(char [] x )
    {
        writefln("Error : %s,x );
        super.return -1;

    }

}

The only problem I can find with this is not knowing the return type of the enclosing function. Remember, you can pass nested functions and anonymous functions forward as pointers: # int myFn(void function() handle){ # handle(); //Fails: tries to squeeze a 'Foobar' through an 'int'. # } # # class Foobar; # # int main(){ # void myTestFn(){ # super.return new Foobar; # } # myFn(&myTestFn); # } AFAIK, D just doesn't have the degree of runtime introspection to keep things like this typesafe. Besides, Exceptions already fill parts of this niche. If you want to use 'goto' like semantics in a more controlled way, there are ways to do it. Perhaps using a switch, nested in a loop to build a state machine is what you need? # char[] myFn(int len){ # enum{ WORKING, DONE, ERROR}; # int state = W0RKING; # char[] value; # if(len <= 0) state = ERROR; # do{ # switch(state){ # case WORKING: value.length==len? state=DONE : value ~= "X"; break; # case ERROR: value = ""; break; # } # }while(state == WORKING); # return value; # } IMO, gotos are still the way to go for special-case, zero-overhead, no-fuss branching within functions. - EricAnderton at yahoo
Apr 21 2005
parent reply Sean Kelly <sean f4.ca> writes:
In article <d48opl$feo$1 digitaldaemon.com>, pragma says...
In article <d48n04$dur$1 digitaldaemon.com>, Charlie says...
Sometimes goto is still the best solution for large functions with many
control paths, where an error action needs to be taken, then return from the
function. If we had something like

int myLargeFunction ()
{

    void onError(char [] x )
    {
        writefln("Error : %s,x );
        super.return -1;

    }

}

enclosing function.

I would consider the proposed syntax only valid for functions declared within other functions, ie. functions that have access to an enclosing scope. But that brings up an interesting point (related to the problem you mention). What if you did this: # void other( void delegate() fn ) # { # fn(); # } # # int outer() { # void inner() { # super.return -1; # } # other( &inner ); # } I would assume that what *should* happen is that scope jumps out of both other() and outer() with a return value of -1, and this seems unacceptable. For this to work there would have to be a rule that functions with this syntax are not allowed to be passed as delegates. And this may be too much of a pain to implement realistically. Sean
Apr 21 2005
parent reply pragma <pragma_member pathlink.com> writes:
In article <d48r2q$htq$1 digitaldaemon.com>, Sean Kelly says...
What if
you did this:

# void other( void delegate() fn )
# {
#     fn();
# }
# 
# int outer() {
#     void inner() {
#         super.return -1;
#     }
#     other( &inner );
# }

I would assume that what *should* happen is that scope jumps out of both other()
and outer() with a return value of -1, and this seems unacceptable.  For this to
work there would have to be a rule that functions with this syntax are not
allowed to be passed as delegates.  

That might be just good enough to work. I wonder what the compiler error message would be?
And this may be too much of a pain to
implement realistically.

D would need some serious runtime introspection to get this right. 'super.return' would have to compile down into a check for the calling function's return-type, and if it matches the argument found in the statement. Then there's the issue of "is this a debug-only" feature, and so forth. When have you heard of a reflection system being able to discern what function called the current scope? Does *any* language do this? Also, there's the low-level details: how does one carry a return value back through the call stack? Use an exception hook perhaps? Its not impossible, but I think it's a tad past the point of diminishing returns. - EricAnderton at yahoo
Apr 21 2005
parent reply "Charlie" <charles jwavro.com> writes:
 Its not impossible, but I think it's a tad past the point of diminishing
 returns.

Yea I hadn't given much thought to the implementation, but nested functions can 'see' variables in its parent function so it must have some information about it ? Charlie "pragma" <pragma_member pathlink.com> wrote in message news:d48s8f$it9$1 digitaldaemon.com...
 In article <d48r2q$htq$1 digitaldaemon.com>, Sean Kelly says...
What if
you did this:

# void other( void delegate() fn )
# {
#     fn();
# }
#
# int outer() {
#     void inner() {
#         super.return -1;
#     }
#     other( &inner );
# }

I would assume that what *should* happen is that scope jumps out of both


and outer() with a return value of -1, and this seems unacceptable.  For


work there would have to be a rule that functions with this syntax are


allowed to be passed as delegates.

That might be just good enough to work. I wonder what the compiler error message would be?
And this may be too much of a pain to
implement realistically.

D would need some serious runtime introspection to get this right. 'super.return' would have to compile down into a check for the calling function's return-type, and if it matches the argument found in the

 Then there's the issue of "is this a debug-only" feature, and so forth.

 When have you heard of a reflection system being able to discern what

 called the current scope?  Does *any* language do this?

 Also, there's the low-level details: how does one carry a return value

 through the call stack?  Use an exception hook perhaps?

 Its not impossible, but I think it's a tad past the point of diminishing
 returns.

 - EricAnderton at yahoo

Apr 21 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
Haven't messed with this yet, but shouldn't typeof(super) give you the answer
to what type "super" is?

I think the biggere concern would be not what type it is,
but what return values are intended to have what meanings.
Of course, as long as super.return is only called from inside of an enclusing
scope,
which I think is the only place that "super" is valid anyway (correct me if I'm
wrong)...
then I would think that the person using it would have
access to the information needed to use it right.
No run-time checking necessary.

On the other hand, while I could see instances where that could do things which
goto can't,
I don't see it as being able to "replace" goto.

TZ

"Charlie" <charles jwavro.com> wrote in message
news:d497qp$tte$1 digitaldaemon.com...
 Its not impossible, but I think it's a tad past the point of diminishing
 returns.

Yea I hadn't given much thought to the implementation, but nested functions can 'see' variables in its parent function so it must have some information about it ? Charlie "pragma" <pragma_member pathlink.com> wrote in message news:d48s8f$it9$1 digitaldaemon.com...
 In article <d48r2q$htq$1 digitaldaemon.com>, Sean Kelly says...
What if
you did this:

# void other( void delegate() fn )
# {
#     fn();
# }
#
# int outer() {
#     void inner() {
#         super.return -1;
#     }
#     other( &inner );
# }

I would assume that what *should* happen is that scope jumps out of both


and outer() with a return value of -1, and this seems unacceptable.  For


work there would have to be a rule that functions with this syntax are


allowed to be passed as delegates.

That might be just good enough to work. I wonder what the compiler error message would be?
And this may be too much of a pain to
implement realistically.

D would need some serious runtime introspection to get this right. 'super.return' would have to compile down into a check for the calling function's return-type, and if it matches the argument found in the

 Then there's the issue of "is this a debug-only" feature, and so forth.

 When have you heard of a reflection system being able to discern what

 called the current scope?  Does *any* language do this?

 Also, there's the low-level details: how does one carry a return value

 through the call stack?  Use an exception hook perhaps?

 Its not impossible, but I think it's a tad past the point of diminishing
 returns.

 - EricAnderton at yahoo


Apr 23 2005