

MetaES – JavaScript in JavaScript interpreter - bartqk
http://metaes.org/

======
anewhnaccount
Previously:
[https://github.com/mozilla/narcissus](https://github.com/mozilla/narcissus)

~~~
bartqk
Yep. But it went nowhere, as far I know.

~~~
omphalos
IIRC I believe tailspin was based partly off the Narcissus codebase. I think
MetaES is better because it gives you a debugger whereas Narcissus isn't
pausable (last I checked). Additionally MetaES is written in plain ES5, which
I think is another plus over Narcissus in terms of general usability.
Narcissus' focus was mainly on prototyping language features and I get the
impression that compatibility was never a concern.

------
robinduckett
Awesome work! I particularly like the code completion.

Would this be quick enough to integrate into an editor like atom.io? For
variable and function completion

~~~
bartqk
That's the plan, although it may take few weeks or months to create something
solid :)

~~~
omphalos
I think there's definitely value in this kind of JavaScript-in-JavaScript type
of dev utility. The main advantage is cross-browser dev utilities - which
brings us closer to a cross-browser dev environment.

Browsers have historically opted for hiding runtime management (debugging,
etc) behind myriad APIs, most of which can't be accessed from the running
program itself. I would love to see a cross-browser way to hook into these
sorts of things without extensions or at least with standard APIs.

Overall this would be much better for us as coders. And this would open the
way for all sorts of cool tools. Consider V8's live code reloading
functionality. But imagine if it worked cross-browser and could be called from
the program itself. Your webserver could send a signal over websocket, and you
could perform hot-swapped deployments of your webpage, and all connected
browsers would be updated. The browsers could be customers', or they could be
inside that mobile device that's a pain to debug.

It would also be much easier to prototype new dev tools and ways of coding.
For example, programming against Chrome's extensions APIs (as great as they
are) is somewhat limiting - last I checked you lack direct access to the
embedded CodeMirror editor for example. There are a lot of security-focused
restrictions. So people workaround this. They rewrite editors and file
managers from scratch so they can get the desired flexibility (lighttable,
brackets, atom, etc).

Personally I love to see projects like MetaES because I feel like they are
inching us closer to something that could be the next step.

~~~
bartqk
Indeed MetaES may be a way to pave a path to new kind of development. Bret
Victor's work, LightTable, Swift Playground and others proved that small
improvements are possible. I believe though, that next bigger step requires
new fundamentals and metacircular interpretation plus smart IDE and partial
evaluation may be very interesting.

I don't know honestly what's going to pop up along the way, but with MetaES we
can get smart completion and better debugging experience in popular editors
for sure, it just requires more work and care.

------
omphalos
Reminds me of [https://github.com/int3/metajs](https://github.com/int3/metajs)

I like this kind of stuff.

A particularly interesting take on this is tailspin, although the repo appears
have been taken down:
[https://github.com/wthimbleby/tailspin](https://github.com/wthimbleby/tailspin)
That one offered a reversible JavaScript debugger written in JavaScript, which
I thought that was very impressive from a technical standpoint.

~~~
bartqk
It is very similar. But MetaES tries to be production ready and reliable. As
far I rememember, tailspin wasn't metacircular, but just an interpreter that
interprets some kind of bytecode created from JavaScript source.

~~~
omphalos
Yeah, it seemed designed for educational examples, and worked within in a VM.
But I couldn't find a way to easily interop with the external JavaScript
environment. It was well-tested though and passed the vast majority of
test262.

MetaJS has some open issues - some related to the fact that it's intended to
let you step through code, which I think makes certain interop scenarios
difficult (let's say for example native code calls MetaJS code and expects a
return value - it's not possible to set a MetaJS breakpoint there because the
native runtime isn't paused).

I would be curious to know how MetaES fares under something like test262. I
think a metacircular interpreter that does well in an extensive suite like
that could indeed be a proper, "safe alternative to eval" (as suggested by
another commenter).

~~~
bartqk
MetaES was tested using test262. Passed most of the cases.

[https://github.com/metaes/metaes](https://github.com/metaes/metaes) \-
"MetaES was tested using test262 test suite. Runnable test suite is currently
not added to the repository."

You're right about breakpoints while code is called by native functions.
That's something that should be discussed more.

~~~
omphalos
Ah, sorry I missed that! Very nice!

------
vmorgulis
Great job.

Do you know this interpreter ? (in D)

[https://github.com/higgsjs/Higgs](https://github.com/higgsjs/Higgs)

It's one of the most advanced I found (outside browsers).

If you want to get rid of the "switch/case", you can look at threaded code
interpreters.

[http://www.complang.tuwien.ac.at/forth/threaded-
code.html](http://www.complang.tuwien.ac.at/forth/threaded-code.html)

You can find useful ressources in Forth about it.

I write a stack-based language in javascript. Each statement is a closure
around the arguments of the expression stored in a flat array. The instruction
pointer is an index in that array. It is partially compiled.

I also use function object constructor for a kind of FFI.

There is also good potential with asm.js to reach near-native performances.

~~~
bartqk
Thanks. Didn't heard of Higgs, but looks interesting. You could use JITting in
MetaES as well, you have all information about execution during runtime, so
why not? That was one of my ideas for demo, but this one is quite heavy ;)

Where's your language's website?

~~~
vmorgulis
[https://github.com/vmorgulys/crabble/tree/master/js/object/m...](https://github.com/vmorgulys/crabble/tree/master/js/object/machine)

It is far less advanced than yours. It's inspired by Forth (a mixture of
interpret and compile "word"s).

I'm doing that right now:

    
    
      let print foreign console.log
      print "hello"
    

Every "word" is a function receiving a stack and returning a stack. Whitespace
can be replace by a "|".

Each line is evaluated from right to left. Some words are used to change the
state of the compiler and the compiler is a state machine (words are events).

The game is to find a minimal set of words to express high-level features like
lambdas (from a word "jump", "until" or "instruction-pointer" for example).

It's cool to program :-)

------
daurnimator
This reminds me of a javascript weirdness I found. When passed as `this`,
primitives (string, number, boolean) get wrapped in their classes.

You can get the 'Number' function with:

    
    
        Number = (function(){return this;}).call(1).constructor

~~~
bartqk
nice trick. You can, but you can't reference `Number` directly, that's the
point. `Number` is a part of standard library, so being in JS it's possible
use hack that you've shown. But you won't find a reference to let's say
`console`, because it's not a part of ECMAScript.

~~~
bartqk
or just `1..constructor` -> function Number().

~~~
daurnimator
> or just `1..constructor` -> function Number().

Ah ha. much simpler :)

------
kparjaszewski
Nice one - during my studies I was implementing the The Spineless Tagless
G-machine in Haskell - @bartqk - maybe you can find this interesting /
inspiring: [http://ow.ly/OBXQ6](http://ow.ly/OBXQ6). Or in general search for
any paper by Simon L. Peyton Jones. (like this one:
[http://ow.ly/OBY0K](http://ow.ly/OBY0K))

------
foldor
This could actually pretty damn cool as a method of using ES6 features and
supporting browsers that don't yet offer it. Of course at a serious
performance penalty I'm sure.

~~~
Skalman
If you don't need to dynamically evaluate the code, compiling ES.next code
will be more performant, e.g. using Babel.

------
daurnimator
Similar project:
[https://benvie.github.io/continuum/](https://benvie.github.io/continuum/)

~~~
bartqk
Yeah, much older project. Looks like it intereprets some kind of IR code, it's
not the case in MetaES, it just executes AST. I don't know either if it allows
interoperate with surrounding interpreter. MetaES interops native code on
purpose.

------
lopatin
This is pretty cool. Maybe can be useful as a safe alternative to eval()?

~~~
bartqk
Could be :) If you accept that it's slower. Benchmarks would show the
difference.

