6 ms·
Awesome. Question: I was under the impression (perhaps mistakenly) that it would be impossible (or very hard) to statically compile a highly dynamic language l
by CoffeeDregs 16y ago
Awesome. Question: I was under the impression (perhaps mistakenly) that it would be impossible (or very hard) to statically compile a highly dynamic language like Javascript. Yes, No? Are there shortcuts Mug takes or disallowed coding styles?
How would Mug handle the following RuPyScript pseudocode:
for i in 1..10; eval "def function$i; print 'I'm $i'; end"; end
- stingraycharles 16y agoI think, by definition, eval () will be impossible in a statically compiled environment.
- CoffeeDregs 16y agoRight, right, but then how useful would Mug be if the dynamic stuff in JS can't be used?
- JonnieCache 16y agoMunging strings and then eval()ing them is the worst way to write dynamic code. Hopefully its not common in most js libraries. Missing eval() is a feature.
- latortuga 16y agoAs a follow up in case anyone is curious about the why behind this assertion, consider a line of code like this eval("myObject."+functionName+"()") Not only does it make it difficult to track down the calls to this method, it is now impossible to minify this chunk of code, something that is very commonly done in javascript. This is why javascript includes things like apply() and accessing members of an object in multiple ways (obj.attribute == obj['attribute'], for user-defined values of attribute).
- deleted 16y ago[deleted]
- phuff 16y agoThe "dynamic stuff" appears to all be included. Just not eval(), which is probably a bad thing for most JS code anyway...
- timcameronryan 16y agoRight. Technically Mug will conform to the ECMAScript 3 Compact Profile: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-327.pdf http://www.ecma-international.org/publications/files/ECMA-ST... Which doesn't include eval() or the with(){} statement (both used infrequently enough that it's not worth the overhead). A REPL would still be possible, however, it would require some work to maintain the current scope between input.
- Autre 16y agoIs there a reason you are not targeting ECMA5 (with the exclusions you mentioned)?
- timcameronryan 16y agoMuch of the runtime has been developing by trying out existing code, then adding support gradually. Of course most of the code I tried out was ECMA3 compliant. I expect to add in support for ECMAScript 5's Object extensions API (defineProperty, getters/setters) as Mug supports them internally, just as Mug already has a global JSON object. The features which could cause incompatibility with existing code is something I'd have to consider separately, so it depends when a majority of authors start writing ECMA5-compliant code (no function.callee, implicit this object bound to global, etc.)
- al_james 16y agoI should imagine it wraps all values in its own flexible typed wrapper class and defines code for operations on them. This, of course, imposes quite an overhead.
- timcameronryan 16y agoSometimes. The primitive types Mug can work with are `double`, `boolean`, `String`, and `JSObject`. This allows arithmetic operations and conditionals to be compiled without wrapping objects, and actual object invocations to be autoboxed as they are in JavaScript (like "a = 10" vs "a = new Number(10)") The gaudy part is that there is only one type of function signature, basically "invoke(Object, Object, Object...)" which means Mug has to convert doubles to Doubles and booleans to Booleans across function calls... so it's somewhat of a tradeoff.
- Autre 16y agoJust tried the following: for (var i = 0; i < 10; i += 1) eval("function function_" + i + "() { print('i am ' + i); }"); for (i = 0; i < 10; i += 1) this['function_' + i](); but it seems like eval is not supported yet - i guess for good reasons.
- lukev 16y agoDepends what you mean by dynamic. If you mean 'dynamically typed', then there's no particular problem - that's mainly a function of how you implement your calling protocols. It's much easier to write a dynamic compiler, actually, since you don't need to catch type errors at compile time. If you mean 'supports eval', as your example seems to indicate, then you'll have to include either a compiler or interpreter in the language runtime - there's really no way around that. But it's not a big deal unless you're in some kind of embedded environment, and in that case you're probably not using a language that supports 'eval' anyway.
- noahlt 16y agoOne of his strategies (from the README on Github) is "favoring static compilation rather than a runtime interpreter", so I suspect that `eval` is not included in Mug. However, `apply` is included (cf. test/regression.js line 19). So your example pseudocode could probably be written like this: for (var i = 1; i <= 10; i++) { var f = function() { print("I'm " + i.toString()); }; f(); }
- timcameronryan 16y agoAs al_james metioned, in order to emulate a dynamic language, you have to take a lowest-common-denominator approach. Thus all objects are of the type JSObject, which has functions for get() set() invoke() etc.-- basically a glorified HashMap+Runnable. However, you don't need to wrap objects for arithmetic operations. At the moment Mug can determine the result of some types of expressions. If you're adding two doubles, it doesn't wrap the numbers before adding them. If you're calling (10).toString(), then it will autobox the number just as defined in the ECMAScript spec (the [[ToObject]] operation). Deterction currently only works where types are explicit (a number literal will always be a number, etc.) The next step is to do type analysis on local variables, which will allow loops like for (var i = 0; i < 10; i++) { ... } to be compiled without wrapping primitives at all, greatly improving speed.