Nice project! One little remark: I see you're being slightly lazy and using JSON to save some value conversion work. One problem is that this is not very good from a performance standpoint. The other, more serious issue is that your code will not work if someone tries to pass around a data structure containing NaN value, like []float64{math.NaN()} Got bitten by this problem, had to fix it: https://github.com/contactless/wb-rules/commit/067ff7564f16a...
Unfortunately NaN behavior seems to be hard-wired in encoding/json code. The proper way to fix it is perhaps taking encoding/json sources and converting marshalling/unmarshalling code to use go-duktape Push/To/etc. functions instead of JSON writing/parsing. That's indeed a sizable amount of work, though.
As of integrating (some of) changes from my fork to the go-duktape mainline, thanks a lot! Didn't get around to do it myself.
I built a package to bridge spidermonkey/Go last year[0]. I ended up doing most of the communication via JSON (after several less stable versions using reflect) which was fine for the use-case I had. Unfortunately since it builds spidermonkey and some wrapper code it ruined any chance of "go get" working cleanly which doesn't make it a very attractive package.
No the contexts in pools do not share any state. Once you call an Eval from Go-land you'll be tied to context until that Eval returns, but Go-land will yield during that time so other goroutines(/contexts) are free to execute. It's just a convenience for setting up and working with multiple contexts to take advantage of multiple cores. Probably better to think of it like a process-pool.
The use case I had was along the lines of:
* Bind/Expose a bunch of Go functions to N JS worker contexts.
* Execute a large queue of JS-functions using the workers.
Spidermonkey did actually have a way to do a kind of shallow copy of a context and save/restore stack, which shared state, however this actually ended up making things much slower for my use as it required locking the threads and constantly copying stacks.
This is pretty interesting, although I don't know if it's... necessary.
What do you think are some of the pros/cons between Go and JavaScript? When would you prefer to use JavaScript instead of Go, or vice versa?
I think Go can be more performant than Node.js, but I remember seeing some conflicting benchmarks where V8 can actually manage more RPS.
The other thing that comes to mind is how React Native uses JavaScript to manipulate UI Components on iOS. If Google ever supports Go on Android, then this kind of thing could be pretty interesting.
the main goal of CandyJS is allow to other developers build extendable programs without the requirement of compile.
A good example could be a chan bot in Go with plugins written on JS. (like https://github.com/djosephsen/lazlo) but with CandyJS the effort to make this will be minimal, since you can use the same structures on JS and Go.
About the performance, CandyJS javascript is much slower than pure Go, since the reflection is very expensive.
Duktape is good for scripting. My particular app is a simple rule engine for smart home applications which runs on relatively low-powered ARM board. It would hardly be practical to have Go compiler there, and duktape is resource-efficient ECMAScript engine which serves this purpose just fine.
the method and field names are converted to lowerCamelCase to be compliant with the JS coding style. Let's see if this transformation becomes a headache.
BTW this behaviour is undocumented, I will fix that.