1. GOTO examples in EUPHORIA´s source
- Posted by Shawn Pringle <shawn.pringle at ?mail.c?m> Jun 05, 2008
- 626 views
I see some examples in EUPHORIA'S source code using goto. There are some macros and I am glad we do not have those in euphoria containing goto. #define thread() goto loop_top #define thread2() {pc += 2; goto loop_top;} #define thread4() {pc += 4; goto loop_top;} #define thread5() {pc += 5; goto loop_top;} #define threadpc3() {pc = (int *)pc[3]; goto loop_top;} #define inc3pc() pc += 3 All of these goto examples can be replaced with 'continue'. I suppose the reason to eliminate goto is to encourage keywords like continue and exit. Then we see a place where goto is used a lot to jump into error handling code from multiple places:
case L_ASSIGN_OP_SUBS: /* var[subs] op= expr */ top = *(object_ptr)pc[1]; aos: if (!IS_SEQUENCE(top)) { //optimize better goto subsfail; } obj_ptr = (object_ptr)SEQ_PTR(top);/* the sequence */
later
top = *obj_ptr; if (!IS_SEQUENCE(top)) { goto asubsfail; } top = (object)SEQ_PTR(top);
... later..
*((object_ptr)top) = (object)obj_ptr; // storing a C pointer thread5(); } goto asubsfail;
Arguably you could use small function calls instead of gotos here. I am told there is a big cost in calling a function. Sometimes I put things into smaller functions just so that I can add convenience functions or I realise I can avoid retyping things over and over. If I had goto and I cared about so much about speed I might use it all over the place, saving labels in a simulated runtime stack and using globals for data passing. If I use functions for call backs and everything else with goto in the way mentioned would I gain speed? If so, wouldn't it make sense for EUPHORIA to compile the source in a way that simulates these gotos for recursive function calls? Isn't it all simulated anyway? So, the differences are, in functions variables are local to the routine's call. That is, The function can call itself without clobbering its own local variables. You can use call_back() to allow calls from C or any language that can call a C function. Suppose a procedure defined inside a routine would work exactly like gosub. There would be no parameter passing but you could modify the routine's variables. Wouldn't this be nearly as fast as goto? It seems that these kinds of procedures defined in routines would allow for gosub style programming. The code pointer is the only thing that gets saved. You can disallow recursive calls and allow only one call to a gosub at a time to avoid a stack structure. If the user needs those things he can use a file scope defined routine. Shawn Pringle
2. Re: GOTO examples in EUPHORIA´s source
- Posted by Jeremy Cowgar <jeremy at cowg?r.c?m> Jun 05, 2008
- 595 views
Shawn Pringle wrote: > > I see some examples in EUPHORIA'S source code using goto. There are some > macros and I am glad we do not have those in euphoria containing goto. > > > #define thread() goto loop_top > #define thread2() {pc += 2; goto loop_top;} > #define thread4() {pc += 4; goto loop_top;} > #define thread5() {pc += 5; goto loop_top;} > #define threadpc3() {pc = (int *)pc[3]; goto loop_top;} > #define inc3pc() pc += 3 > > All of these goto examples can be replaced with 'continue'. I suppose the > reason to eliminate goto is to encourage keywords like continue and exit. > That's not the case. Euphoria internally uses different methods to jump from routine to routine based on what the compiler allows. There is direct threading, indirect threading, call threading (which is function calling and is the slowest), switch threading (often uses goto), etc... The fact that goto is used here is due to speed. Euphoria is one fast interpreter, you goof with it's uses in the macros you stated here and out the door goes any type of speed. We would start comparing our language speed to Ruby and Python instead of compiled languages. -- Jeremy Cowgar http://jeremy.cowgar.com
3. Re: GOTO examples in EUPHORIA´s source
- Posted by Matt Lewis <matthewwalkerlewis at ?ma?l.com> Jun 05, 2008
- 592 views
Shawn Pringle wrote: > > I see some examples in EUPHORIA'S source code using goto. There are some > macros and I am glad we do not have those in euphoria containing goto. > > > #define thread() goto loop_top > #define thread2() {pc += 2; goto loop_top;} > #define thread4() {pc += 4; goto loop_top;} > #define thread5() {pc += 5; goto loop_top;} > #define threadpc3() {pc = (int *)pc[3]; goto loop_top;} > #define inc3pc() pc += 3 > > All of these goto examples can be replaced with 'continue'. I suppose the > reason to eliminate goto is to encourage keywords like continue and exit. That's true, though these are only used with -DINT_CODES. It's basically a fall back position in case the compiler doesn't support either the GNU style gotos: // these GNU-based compilers support dynamic labels, // so threading is much easier #define thread() goto *((void *)*pc) #define thread2() {pc += 2; goto *((void *)*pc);} #define thread4() {pc += 4; goto *((void *)*pc);} #define thread5() {pc += 5; goto *((void *)*pc);} #define inc3pc() pc += 3 #define BREAK goto *((void *)*pc) ...or Rob's low level hack: #pragma aux thread = \ "jmp [ECX]" \ modify [EAX EBX EDX]; These *can't* be replaced with continue, or we'd really lose a lot of the great speed of euphoria. > Then we see a place where goto is used a lot to jump into error handling code > from multiple places: [Note that I've included some additional code before and after your example.]
case L_PASSIGN_OP_SUBS: // temp has pointer to sequence top = **(object_ptr *)pc[1]; goto aos; case L_ASSIGN_OP_SUBS: /* var[subs] op= expr */ top = *(object_ptr)pc[1]; aos: if (!IS_SEQUENCE(top)) { //optimize better goto subsfail; } obj_ptr = (object_ptr)SEQ_PTR(top);/* the sequence */ top = *(object_ptr)pc[2]; /* the subscript */ pc[9] = pc[1]; // store in ASSIGN_SUBS op after length-4 binop if ((unsigned long)(top-1) >= ((s1_ptr)obj_ptr)->length) { /* possibly bad subscript */ tpc = pc; top = recover_rhs_subscript(top, (s1_ptr)obj_ptr); } top = (object)*(top + ((s1_ptr)obj_ptr)->base); a = pc[3]; pc += 4; if (IS_ATOM_INT(top)) { if (IS_ATOM_INT_NV(*(object_ptr)a)) { *(object_ptr)a = top; thread(); BREAK; } else { DeRefDSx(*(object_ptr)a); *(object_ptr)a = top; thread(); BREAK; } } else { RefDS(top); DeRefx(*(object_ptr)a); *(object_ptr)a = top; thread(); BREAK; } case L_PASSIGN_SUBS:
> later <snip> > Arguably you could use small function calls instead of gotos here. I am > told there is a big cost in calling a function. There is a cost. Though in these cases, speed isn't real important, because it's just going to display an error and quit. I sort of wonder why those were left as gotos myself A more interesting case is the "goto aos;" statement, which allowed use of different initialization code without imposing the cost of a test, or of repeating the code (the fastest solution), increasing the maintenance cost. Note that there are many more lines to implement this opcode, so the repetition would *not* be trivial. This was obviously a case where the optimization was more valuable than the avoidance of a goto. I'll also take this moment to point out that this would be *one* of the places that would have to be modified to deal with an 8-bit value. :( > Sometimes I put things into smaller functions just so that I can add > convenience functions or I realise I can avoid retyping things over and > over. If I had goto and I cared about so much about speed I might use > it all over the place, saving labels in a simulated runtime stack and > using globals for data passing. If I use functions for call backs and > everything else with goto in the way mentioned would I gain speed? > If so, wouldn't it make sense for EUPHORIA to compile the source in a > way that simulates these gotos for recursive function calls? Isn't it > all simulated anyway? In general, refactoring into smaller routines makes maintenance easier (there are limits, of course). I usually don't worry too much about optimization until I find a need, though there are several rules of thumb I tend to follow, such as storing a subscript in a separate variable if I'm going to reuse it (of course, this also reduces bugs, since I only have to get the subscript correct once). What do you mean by 'compile'? Native euphoria routine calls do not normally use up any additional stack space (the exception is if you're using the multitasking stuff). The stack for euphoria calls is maintained on the heap, and it still has to hide/initialize/destroy private variables, which does have some memory and time overhead. In a translated euphoria app, the routines are regular C routines which do use up stack space. Matt
4. Re: GOTO examples in EUPHORIA´s source
- Posted by MBianchi <mebian at ti?cal?net.it> Jun 05, 2008
- 603 views
Jeremy Cowgar wrote: > <snip> > > The fact that goto is used here is due to speed. Euphoria is one fast > interpreter, > you goof with it's uses in the macros you stated here and out the door goes > any type of speed. We would start comparing our language speed to Ruby and > Python > instead of compiled languages. > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> Please let my *newbie* opinion enter this passionate discussion. I have no technical suggestions to give, but a *big* doubt rises in my mind, after reading all posts about goto ..... If you think that you should start comparing Eu with Python or any other interpreter, you'll soon find yourself relaxing the specs to the point that Eu will be no more attractive for new users, for there are many other languages out there with an unbeatable support. If you want to compare Eu to other languages, you should perhaps take Cython (or Pyrex), or better Ocaml (or even Lisaac for OO fans) as benchmarks competitors, not Ruby or Python, as good as they are doing their jobs, anyway. After all, if the creator of this language put so many efforts in optimizing it and speeding it up, comparing it to C, why kicking his back for his kindness giving up with the very basilar principle of a search for speed from which Eu was born ..... ??? (this has nothing to do with the road to perfection that every programming language tries to find IMHO) (my two cents, with no offence intended for anyone's opinion) Cheers. MBianchi
5. Re: GOTO examples in EUPHORIA´s source
- Posted by Jeremy Cowgar <jeremy at ?owg?r.com> Jun 05, 2008
- 605 views
MBianchi wrote: > > Jeremy Cowgar wrote: > > > <snip> > > > > The fact that goto is used here is due to speed. Euphoria is one fast > > interpreter, > > you goof with it's uses in the macros you stated here and out the door goes > > any type of speed. We would start comparing our language speed to Ruby and > > Python > > instead of compiled languages. > > > > If you think that you should start comparing Eu with Python or any other > interpreter, > you'll soon find yourself relaxing the specs to the point that Eu will be no > more attractive for new users, for there are many other languages out there > with an unbeatable support. > I agree with the rest of your message and is why I am using Euphoria. But in the above I think you misunderstood me. I said that if we convert from using goto's in the Euphoria back end and move to something like call-threading then we will be on par with the speed of Python and Ruby. It was suggested that the goto's be converted to a while loop. That would kill one thing we all like about Euphoria, it's speed. If we did that merely to get rid of the goto disaster that *always* happens when a language contains goto, then that would be a *huge* dis-service to Euphoria. -- Jeremy Cowgar http://jeremy.cowgar.com
6. Re: GOTO examples in EUPHORIA´s source
- Posted by MBianchi <mebian at t?sca?inet.it> Jun 05, 2008
- 626 views
Jeremy Cowgar wrote: > > MBianchi wrote: > > > > Jeremy Cowgar wrote: > > > > > <snip> > > > > > > The fact that goto is used here is due to speed. Euphoria is one fast > > > interpreter, > > > you goof with it's uses in the macros you stated here and out the door > > > goes > > > any type of speed. We would start comparing our language speed to Ruby and > > > Python > > > instead of compiled languages. > > > > > > > If you think that you should start comparing Eu with Python or any other > > interpreter, > > you'll soon find yourself relaxing the specs to the point that Eu will be no > > more attractive for new users, for there are many other languages out there > > with an unbeatable support. > > > > I agree with the rest of your message and is why I am using Euphoria. But in > the above I think you misunderstood me. I said that if we convert from using > goto's in the Euphoria back end and move to something like call-threading then > we will be on par with the speed of Python and Ruby. It was suggested that the > goto's be converted to a while loop. That would kill one thing we all like > about > Euphoria, it's speed. If we did that merely to get rid of the goto disaster > that *always* happens when a language contains goto, then that would be a > *huge* > dis-service to Euphoria. > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> You're right, I misunderstood. My fault and my apologies for that. Cheers. MBianchi