Skip to content
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

RFC: default Ruby return behavior as Result<AnyObject, AnyException> #91

Open
danielpclark opened this issue Feb 21, 2018 · 1 comment

Comments

@danielpclark
Copy link
Contributor

danielpclark commented Feb 21, 2018

I've put comments through numerous issues on this and it doesn't make sense to me to leave any of this discussion so scattered so I'm opening this issue to discuss the merits of designing the default behavior where ever AnyObject would return to be Result<AnyObject, AnyException>.

Pros

  • For anyone developing a Rust app and using Ruby from it then this would allow for “The Rust Way” of handling Ruby exceptions to be well written and used. As well as have the advantage of Rust's question mark syntax let val = some_result?;.

Cons

  • Implementing this behavior would require the majority of features to be run through Ruby's rb_protect which will catch exceptions and allows us to build the Result. This adds cost to the performance. When writing a Ruby program and using Rust to gain performance you don't necessarily want this added cost in performance as the major draw to use Rust in Ruby is all about performance.
  • probable re-write & major version change

Exceptions to the Rule

Some scenarios won't “ever” *cough* *cough* call for an exception to be raised like when doing equality checks. Equality checks simply make sense to return the bool type for convenience. Although any method that can be monkey-patched and rewritten may raise exceptions in which case that should use protect. The choice for design and usage would then come down to how strict to adhere to The Rust Way pattern in case of risk, or provide the end user more of a choice. My thoughts on this point is to be more relaxed on enforcing the return type and trust the developers to understand the risks and choose there own implementation decisions.

Alternatives

Looking at a Helix PR with_protect example gave me the idea to have an impl WithProtect on FnOnce() trait. It's just a rough idea but it would be something like lazily produce a FnOnce() closure and have that take &self for the method definition in the WithProtect trait to route the code through something like my protect_send method (#88). So we could do my_closure.with_protect() to run it.

Strictness

If the need for safety comes first and we choose a relaxed stance on enforcing Result return types then it would come down to where we choose to draw the line. Like, for example, when instantiating a new object both new and initialize methods are highly likely to raise an exception if the startup standards for that object are not met. However the alternative method allocate is nearly guaranteed to never do anything that would raise an exception so this would be one method not needing the Result return type.

Choosing a form of this as a relaxed standard will require a more case by case decision on implementing it. That would likely be the sole choice of the author of this project on his beliefs and weighting on the likeliness of any particular method to raise an exception.

My Stance

I'm not too picky about this change being implemented. With protect_send #88 and eval #79 developers should have enough to take the risk out of most scenarios. But this will require programmers to be more defensive and more on guard with their code when working with ruru. Perhaps the easiest solution would be the alternative I've proposed here above.

I leave this RFC here open for discussion.

@danielpclark
Copy link
Contributor Author

danielpclark commented Mar 1, 2018

It's come to my attention upon further thinking on this subject that there is two contexts to deal with here. One is a Rust program taking advantage of Ruby and the other is a Ruby program taking advantage of Rust.

I believe there is a need for the Error kind which is currently in Rust/ruru for the Rust program side. But I do also believe we need an Exception/AnyException type for dealing with Ruby centric programs. In my minds eye I see this full implemented as AnyException being the core type used everywhere and the Error type as a wrapper to contain behavior on Rust side for Rust applications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant