1. Suggested enhancement
- Posted by JEFF ZEITLIN <jeff.zeitlin at EXECNET.COM> Apr 17, 1997
- 1271 views
I had previously made a suggestion for something equivalent to BASIC's "CHAIN" statement; several people gave some quite useful suggestions as to how roughly equivalent functionality could be implemented. I have been using them, with acceptable results (though I still think a CHAIN would be marginally better). Today, however, inspiration walked up behind me and whacked me upside the head with a two-by-four, which leads to an Idea that I think, if implemented, would be quite a nifty (dare I say "elegant") enhancement to Euphoria: Allow a procedure/function call "execute" (or something along those lines) which takes a sequence of characters forming valid Euphoria statements, and returns whatever executing those statements results in - or nothing at all, if there's no return value in the statements. This would allow: 1. A CHAIN facility - read a Euphoria program text into the variable foo, then "execute(foo)". 2. A macro facility for any Euphoria program - let the user define macros using Euphoria, and any interface that the program author feels is best for the purpose, then "execute(macrovariable)". 3. A procedural parameter capability - you could write highly generic routines without needing to redefine procedures or functions for (for example) comparisons. "function sort(fooseq, compareproc) ... if execute(compareproc) = -1 then ..." 4. A dynamic code facility - since "includes" are idempotent, and cannot be done except at the absolute top level of the program, there's no simple way of defining what gets done "on the fly" such that you can have the Euphoria-knowledgeable user instruct you as to how to handle unforseen situations, and be able to implement those solutions immediately (i.e., without shutting down and restarting the program). "while 1 do ... userproc = ... execute(userproc) ..." Comments? Questions? Discussion? ========================================================================= Jeff Zeitlin jeff.zeitlin at execnet.com --- ~ OLXWin 1.00b ~ I have seen the future and it is now the past.
2. Re: Suggested enhancement
- Posted by John DeHope <jwap at SOUTHEAST.NET> Jan 16, 1997
- 1257 views
- Last edited Jan 17, 1997
JEFF ZEITLIN wrote: > Allow a procedure/function call "execute" (or something along > those lines) which takes a sequence of characters forming > valid Euphoria statements, and returns whatever executing > those statements results in - or nothing at all, if there's no > return value in the statements. I have used a program language/environment called "MUMPS" which provided this functionality. It allows your code to write code, a really interesting feature, eh? I just thought I'd let everybody know that this can be/has been done before.
3. Re: Suggested enhancement
- Posted by Michael Packard <lgp at EXO.COM> Apr 17, 1997
- 1195 views
On Thu, 16 Jan 1997, John DeHope wrote: > I have used a program language/environment called "MUMPS" which provided > this functionality. It allows your code to write code, a really > interesting feature, eh? I just thought I'd let everybody know that this > can be/has been done before. > That's be great! I can just let my games write new games and I can take a vacation! When's that new version coming out? =) Michael Packard Lord Generic Productions lgp at exo.com http://exo.com/~lgp A Crash Course in Game Design and Production http://exo.com/~lgp/euphoria
4. Re: Suggested enhancement
- Posted by "Carl R. White" <C.R.White at COMP.BRAD.AC.UK> Apr 18, 1997
- 1250 views
On Thu, 16 Jan 1997, John DeHope wrote: > JEFF ZEITLIN wrote: > > Allow a procedure/function call "execute" (or something along > > those lines) which takes a sequence of characters forming > > valid Euphoria statements, and returns whatever executing > > those statements results in - or nothing at all, if there's no > > return value in the statements. > > I have used a program language/environment called "MUMPS" which provided > this functionality. It allows your code to write code, a really > interesting feature, eh? I just thought I'd let everybody know that this > can be/has been done before. It was also done in the BBC Microcomputer's BASIC. The command EVAL() let you enter a string comprising any mathematical function available on the computer, (including established variables) and returned the result. e.g. A = 17: B = 42: C = EVAL("SQR(B - A)") and C would be set to 5. It looks like I'm gonna be around for a while..., :) Carl -- Carl R White | e-mail...: crwhite at comp.brad.ac.uk | finger...: crwhite at dcsun1.comp.brad.ac.uk | web......: http://www.student.comp.brad.ac.uk/~crwhite
5. Re: Suggested enhancement
- Posted by Cameron Kaiser <spectre at ODIN.EGATE.NET> Apr 18, 1997
- 1325 views
> It was also done in the BBC Microcomputer's BASIC. The command EVAL() let > you enter a string comprising any mathematical function available on the > computer, (including established variables) and returned the result. > > e.g. > A = 17: B = 42: C = EVAL("SQR(B - A)") > > and C would be set to 5. <nothing-to-do-with-euphoria> LISP does that too, lest anyone forget, as well as some variants of LPC, the programming language that powers some kinds of MUDs and the Roxen httpd. The Amylaar version specifically has a structure called a "closure" that can be written up by the routine on the fly. And, in the totally obscure category, an old COMPUTE!'s Gazette utility called "Smart VAL" lets the VAL() function on Commodore 64 BASIC 2.0 act identically to the example above. </nothing-to-do-with-euphoria> Cameron Kaiser http://www.sserv.com/ spectre at sserv.com
6. Re: Suggested enhancement
- Posted by banjo <banjo at SQUIZ.CO.NZ> Apr 19, 1997
- 1240 views
JEFF ZEITLIN suggested: > Allow a procedure/function call "execute" (or something along > those lines) which takes a sequence of characters forming > valid Euphoria statements, and returns whatever executing > those statements results in - or nothing at all, if there's no > return value in the statements. This would allow: > > 1. A CHAIN facility - read a Euphoria program text into the > variable foo, then "execute(foo)". If the his would add powerful tools, especially for an array of functions. ie. function calculate ( number1, number2, operator ) VirtualMachine = { "add", "subtract", "multiply", "divide" } foo = VirtualMachine[operator] & "(number1, number2)" return execute(foo) --ie execute( "add(number1, number2)" ) end function > > 2. A macro facility for any Euphoria program - let the user > define macros using Euphoria, and any interface that > the program author feels is best for the purpose, > then "execute(macrovariable)". > > 3. A procedural parameter capability - you could write highly > generic routines without needing to redefine > procedures or functions for (for example) > comparisons. "function sort(fooseq, compareproc) ... > if execute(compareproc) = -1 then ..." I don't understand this one. > > 4. A dynamic code facility - since "includes" are idempotent, > and cannot be done except at the absolute top level > of the program, there's no simple way of defining > what gets done "on the fly" such that you can have > the Euphoria-knowledgeable user instruct you as to > how to handle unforseen situations, and be able to > implement those solutions immediately (i.e., without > shutting down and restarting the program). > "while 1 do ... userproc = ... execute(userproc) ..." This is exactly what i want. Especially if the imported procedures could be stored in a precompiled form, with necessary stubs to slot right in, fast... and of course could recieve paramters and return. And if they could call imported procedures, then you'd need some method to avoid infinte regression and overflowing the stack, etc. I'd favour a system variable that let you set the size of the stack, and whether the overflow would exit the program or be a 'soft error' that ended the function, returning a NULL or somesuch. I'd like to know more how the interpreter works, does it create bytecode ?? Can that bytecode be loaded on the fly. If these are too much, then can i have this... The "switch to" statement (a specialized version of Case, stripped for speed) switch to variable { code for variable = 0; -- seperated by semi-colons code for variable = 1; ... code for variable = n; } code for else -- optional, handles variable <> 0 - n end switch multiple lines of code ie. function VirtualMachine ( OPCODE var1 ) switch to OPCODE { Stack = {} ; Stack = Stack & Heap[ var1 ] ; Heap[ var1 ] = Stack[ length(Stack) ] ; Stack = Stack[ 1 ... length(Stack) - 1 ] ; ... etc .. } end switch end function -banjo
7. Re: Suggested enhancement
- Posted by JEFF ZEITLIN <jeff.zeitlin at EXECNET.COM> Apr 19, 1997
- 1239 views
David Cuny wrote (I received this via private mail - I think it probably meant to go to the list)... A::>Jeff Zeitlin suggested being able to pass a sequence of Euphoria code to ::>Euphoria. A::>Sounds like a good suggestion. The biggest problem I can think of would be ::>when an error occured, how would you know *where* it occured? Well, the ex.err dump would show that it happened on an EXECUTE statement/function, and would dump the variables. One of the dumped variables would be the executed code - so you would at least be able to pin it down by that much. If it wasn't passed as a variable, there wouldn't be a lot of code to desk check; it's unlikely in the extreme that one would write more than about a line of code this way - and I can't think of any real reason why someone would want to do so, rather than just writing it directly into the program. Wait, yes I can, but there's still not going to be much code. In the case where it happens in a large chunk of code in a variable, I think it might depend on how it is actually implemented; if I were doing this, I would most likely make it a "back door" to the parser and interpreter routines - much like JPSoftware did when they added the %@EXEC[] function to 4DOS. There would be a small performance hit for EXECUTEd code, but... Anyway, I see no reason why the ex.err report couldn't at least print the offending statement "in EXECUTE parameter" - for example program.ex:41 attempt to divide by 0 in "? 1/0" in EXECUTE parameter Global & Local Variables ...etc. A::>If Robert doesn't want to put this together, one of the list members would ::>certainly be able to write this. Obviously, there would be a performance hit ::>taken if it were coded in Euphoria, but it is doable. Certainly it is - but you'd have to write both the parser _and_ the interpreter, and if you wanted access to Euphoria's debugging facilities, you'd have to write the debugger and trace facilities as well. We'd be talking _major_ performance hit; it might be acceptable if the language you're parsing isn't Euphoria and isn't easily translatable into Euphoria - but I doubt that many people would find it so. One of the major benefits of Euphoria, IMO, is that it is _fast_ and _compact_ - enough so to impress the Borland that wrote the original Turbo Pascal. I don't think that my EXECUTE proposal would slow it down into the realm of most language interpreters; one would gain the flexibility of a LISP interpreter without having to sacrifice the simplicity or a significant portion of the speed of Euphoria. A::>Euphoria itself certainly has an interesting parser, and is lazy when it ::>comes to parsing lines. For example, I can have the line: A::> puts( {}, 1 } A::>and Euphoria parses it happily, only paying attention to the number of ::>arguments (and whether any arguments require parameters), and not attempting ::>any further validation until the line is actually run. Interesting - I would have expected that the built-ins, at least, would have at least as strong type-checking as the user-written routines. OTOH, that might have made it unacceptably difficult to permit overriding of those routines with user code. A::>Also, the 'end' keyword is not part of the language. For example, if you try ::>to run the following code: A::> end A::>you don't get an "unmatched end" error, you get an "unknown command". I get ::>the feeling that each of the structure have their own parsing routines, that ::>scan the input until they find a matching "end" clause. Possibly - it's certainly how I would think to do it... A::>The biggest problem in coding a Euphoria parser in Euphoria is the lack of ::>forward declarations. I'm not sure I perceive why forward declarations would be necessary - would you be willing to elucidate? ========================================================================= Jeff Zeitlin jeff.zeitlin at execnet.com --- ~ OLXWin 1.00b ~ ..... Help!, The TD has fallen and it can't get up!
8. Re: Suggested enhancement
- Posted by Carlos Jose Gonzalia <gonzalia at CRIBA.EDU.AR> Apr 21, 1997
- 1211 views
Jeff Zeitlin wrote: > I'm not sure I perceive why forward declarations would be > necessary - would you be willing to elucidate? In most cases you can do the same job as a mutual recursion does if you just rewrite the algorithm, but this can be difficult and makes the code hard to read. The reason why this matters so much for parsers is that parser algorithms are naturally mutually recursive, since their grammar form (EBNF, context-free grammar or syntax diagram) is by definition mutually recursive. As regards to efficiency, a good grammar-based parser (by this I mean the grammar is "factored non-left-recursive") is practically as efficient as a non-mutually recursive parser. Check any good text on compiler construction for details. > 3. A procedural parameter capability - you could write highly > generic routines without needing to redefine > procedures or functions for (for example) [cut] This is the best proposed enhancement to Euphoria I've heard till now... Wish I had come with it ;)! I believe it's possible to embed this feature into the language in one of two different ways, so to keep type-safety: 1. Allow fully general procedure/function parameters types, for example, a function that sorts an arbitrary sequence of objects in some user-defined order would have as header function sort (sequence nonsorted, function less_eq(object a, object b)) or something similar. The trouble with this approach is that the proc/fun parameters could have their own proc/fun parameters. This makes for a difficult interpreter implementation, and considerable execution overheads if used extensively. The type-checking issues are also very difficult to deal with, unless one restricts the allowed types of the proc/fun's arguments. All this is due to the more complex calling mechanism and the possibility of having a proc/fun argument reference its static context (non local variables known only to itself) when it is called inside the routine it was passed to. 2. Allow restricted procedure/function parameter types, such that their argument is just an "object", not another proc/fun. This would put all the effort of type-consistency in the programmer's hands, in a way much like the type idea of Euphoria, so it fits nicely in that scheme. I believe 2 would be the best choice for the enhancement. I'm not sure having dynamic run-time macro facilities would be an advisable idea. Just think all the parsing, type-checking and precompiling that will happen with all those macros moving around the program... Cameron Kaiser mentioned the possibility of using closures, but the implementation of closures is very expensive both in time and space... Somebody suggested the idea of having proc/fun types could be useful for having sequences of proc/funs (sorry, I can't find the exact reference between the lots of e-mails here). This is very difficult to have in Euphoria, since you would be able to put type incompatible functions in the same list, and then sometime later call the functions stored in the list. This obviously requires a lot of type information to be mantained besides those functions in the sequence (this is called a "descriptor"). Managing all that type info would be difficult, and there is also needed information about the static context of all those functions. This mandatory dynamic type checking would cause a significant overhead to the execution time, too. In short, I believe the idea of restricted proc/fun argument types would be a great thing to have, but it shouldn't be as general as the mentioned features for efficiency problems would arise. ----------------------------- Carlos Gonzalia, Universidad Nacional del Sur Bahia Blanca, Argentina. gonzalia at criba.edu.ar -----------------------------