New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supporting return in blocks #130

Closed
tillda opened this Issue Oct 19, 2012 · 9 comments

Comments

Projects
None yet
5 participants
@tillda

tillda commented Oct 19, 2012

I'm pretty skilled in both JS and Ruby, so I was wondering how would you compile this:

def find_even iterable
  iterable.each { |x| return x if x % 2 == 0 }
end

puts find_even [1, 3, 5, 6]
#6

It seems to me pretty tough to do both blocks and functions in JS and if I'm trying it right it doesn't work for me (it should return 6).

Any plans or thoughts on that?

@elia

This comment has been minimized.

Show comment
Hide comment
@elia

elia Oct 21, 2012

Member

Related: #135

Member

elia commented Oct 21, 2012

Related: #135

@charliesome

This comment has been minimized.

Show comment
Hide comment
@charliesome

charliesome Oct 22, 2012

Contributor

You'd probably need to use an exception here - at least that's how I implemented this in my experimental Ruby to PHP compiler

Contributor

charliesome commented Oct 22, 2012

You'd probably need to use an exception here - at least that's how I implemented this in my experimental Ruby to PHP compiler

@meh

This comment has been minimized.

Show comment
Hide comment
@meh

meh Oct 22, 2012

Member

AFAIK there was support for this, there's probably a bug in the optimization recognition.

Member

meh commented Oct 22, 2012

AFAIK there was support for this, there's probably a bug in the optimization recognition.

@adambeynon

This comment has been minimized.

Show comment
Hide comment
@adambeynon

adambeynon Oct 22, 2012

Contributor

As @charliesome says, to get full functionality, exceptions needed to be used, which really is a pain (in terms of ugly code generation and whatever performance losses on the blocks). Its one of those areas where Im trying to look for a better solution. The generator could follow the method of detecting break. This just checks the return values of blocks, and may be able to optimize a block return without exceptions in the majority of cases. Will look into it anyway.

Contributor

adambeynon commented Oct 22, 2012

As @charliesome says, to get full functionality, exceptions needed to be used, which really is a pain (in terms of ugly code generation and whatever performance losses on the blocks). Its one of those areas where Im trying to look for a better solution. The generator could follow the method of detecting break. This just checks the return values of blocks, and may be able to optimize a block return without exceptions in the majority of cases. Will look into it anyway.

@adambeynon

This comment has been minimized.

Show comment
Hide comment
@adambeynon

adambeynon Oct 27, 2012

Contributor

Realistically this isnt going to be implemented by Opal, as raising/catching exceptions would be the only ideal way to do it, and thats not really ideal itself. In this specific instance, you could use Enumerable#find instead. Might reopen one day if some other clever way of handling this statement comes up.

Contributor

adambeynon commented Oct 27, 2012

Realistically this isnt going to be implemented by Opal, as raising/catching exceptions would be the only ideal way to do it, and thats not really ideal itself. In this specific instance, you could use Enumerable#find instead. Might reopen one day if some other clever way of handling this statement comes up.

@adambeynon adambeynon closed this Oct 27, 2012

@charliesome

This comment has been minimized.

Show comment
Hide comment
@charliesome

charliesome Oct 27, 2012

Contributor

If I get around to it, I might try and implement this. It will require exceptions, but some trickery can be done so that we only need the try/catch for the few blocks that will return early.

FWIW, this is implemented in MRI with setjmp/longjmp - which is basically the C equivalent of exceptions.

Contributor

charliesome commented Oct 27, 2012

If I get around to it, I might try and implement this. It will require exceptions, but some trickery can be done so that we only need the try/catch for the few blocks that will return early.

FWIW, this is implemented in MRI with setjmp/longjmp - which is basically the C equivalent of exceptions.

@adambeynon

This comment has been minimized.

Show comment
Hide comment
@adambeynon

adambeynon Oct 27, 2012

Contributor

Inside the parser, @scope is the current scope, so if a return is detected, we could mark it there so we know if we do need to add a try/catch loop inside the method body. That does sound a nice enough solution. An error is created in runtime.js for breaks (even though theyre not implemented with exceptions anymore), so adding a hardcoded one for returns is probably a good idea too.

Foo.prototype.$method = function() {
  try {
    // block raises __opal.return_err
  }
  catch (err) {
    if (err === __opal.return_err) {
      return err.$v;
    }
    throw err;
  }
};
Contributor

adambeynon commented Oct 27, 2012

Inside the parser, @scope is the current scope, so if a return is detected, we could mark it there so we know if we do need to add a try/catch loop inside the method body. That does sound a nice enough solution. An error is created in runtime.js for breaks (even though theyre not implemented with exceptions anymore), so adding a hardcoded one for returns is probably a good idea too.

Foo.prototype.$method = function() {
  try {
    // block raises __opal.return_err
  }
  catch (err) {
    if (err === __opal.return_err) {
      return err.$v;
    }
    throw err;
  }
};
@charliesome

This comment has been minimized.

Show comment
Hide comment
@charliesome

charliesome Oct 27, 2012

Contributor

This is basically what I was thinking of doing. Should I have a crack at it?

Contributor

charliesome commented Oct 27, 2012

This is basically what I was thinking of doing. Should I have a crack at it?

@adambeynon

This comment has been minimized.

Show comment
Hide comment
@adambeynon

adambeynon Oct 27, 2012

Contributor

Yeah, it is quite an elegant solution. If your happy to work on it, then go for it. Let me know if there is anything you need assistance with

Contributor

adambeynon commented Oct 27, 2012

Yeah, it is quite an elegant solution. If your happy to work on it, then go for it. Let me know if there is anything you need assistance with

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment