Thread overview
Nested functions return from parent functions
Apr 21, 2005
Charlie
Apr 21, 2005
Sean Kelly
Apr 21, 2005
pragma
Apr 21, 2005
Sean Kelly
Apr 21, 2005
pragma
Apr 21, 2005
Charlie
Apr 23, 2005
TechnoZeus
April 21, 2005
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


April 21, 2005
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


April 21, 2005
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
April 21, 2005
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;
>>
>>    }
>>
>>}
>>
>The only problem I can find with this is not knowing the return type of the 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


April 21, 2005
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
April 21, 2005
> 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
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


April 23, 2005
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
> 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
>
>