These are chat archives for opal/opal

28th
Oct 2017
Elia Schito
@elia
Oct 28 2017 09:19
@janbiedermann looks related to constant lookup, if given a repro of any kind I can try looking into it (or give directions for anyone wanting to try)
Jesus Castello
@matugm
Oct 28 2017 12:43
Hi :)
Would Opal be a good solution for evaluating code on a "interactive coding exercises" kind of site?
Instead of evaluating the code on the server & having to sandbox everything.
Xavier Riley
@xavriley
Oct 28 2017 19:43

Hi :wave:

I'm hoping to use Opal to implement a subset of Sonic Pi (a Ruby based live coding music environment http://sonic-pi.net/) in the browser with web audio. Most of that should be straightforward but a key part of that API is how it uses multiple threads with calls to sleep.

While I don't have threads in JS, I can approximate a non-blocking sleep with the following:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function kick() {
  console.log("boom")
  await sleep(1000);
}

async function hihats() {
  console.log("tick")
  await sleep(500);
  console.log("tick")
  await sleep(500);
}

// viewing the console shows these execute concurrently
kick();
hihats();

In terms of porting to Opal, I had the following idea. If a class is bridged from an AsyncFunction, the parser could check for

(async function(){}).constructor.name === "AsyncFunction"

and add the async keyword in front of the function call for generated methods. That would allow for something like the following:

%x{
  var async_bridge_class_demo = Object.getPrototypeOf(async function(){}).constructor;
  async_bridge_class_demo.prototype.$sleep = function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); };
}

class BridgeFoo < `async_bridge_class_demo`
  def self.baz
    puts "in block"
    `await #{sleep(2000)}`
    puts "still in block"
  end
end

BridgeFoo.baz

At the moment this fails because the await keyword is placed inside a non-async generated function.

Firstly, does this seem like a reasonable approach? Secondly, is this the kind of thing that I'd use a rewriter for?

Ideally I'd like to be able to make the await implicit so that sleep(2000) doesn't have to be placed in backticks but I can't think of a better way at present.

Xavier Riley
@xavriley
Oct 28 2017 20:41
sorry for the noise - I'm still reading up. I'll try to put together a PR once I understand it a bit better
assuming you have modern browser for the say part
Elia Schito
@elia
Oct 28 2017 23:56

@xavriley what about explicitly using the async keyword with something like this:

class Foo
  JS.async def bar
    JS.await sleep(2000)
  end
end

JS is already used for direct JS calls so it kinda make sense to me to have a special case in the compiler for async/await support…

@iliabylich @meh thoughts?