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: or return syntax #53

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ctrlaltmilk
Copy link

A small syntax extension to make handling nil values easier and more concise.

Rendered

@dphfox
Copy link

dphfox commented Aug 23, 2024

I would really desperately want to see this - my code is littered with places this would be incredible - but a similar idea I mentioned a while back about "return in expressions" got shot down.

I really hope there is an expression of this design that can be agreed upon.


## Summary

The `or return` syntax is a more compact, understandable way to end execution if an expression evaluates to `nil`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent with usual truthiness test. What if the expression evaluates to false?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should have clarified here - the main use case is for expressions that can return nil, but the already-established truthiness rules would be respected.

@bradsharp
Copy link

Would or break also make sense? I wonder if we could just allow return and break in expressions where they would otherwise make sense.

Comment on lines +41 to +43
local humanoid = partParent:FindFirstChild("Humanoid") or return

humanoid.Health = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just if local which is proposed in a different RFC, so this isn't a strong motivator.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if local does also solve this problem, but it also creates a new indentation level which is counter to the goals of this RFC.

```
and compact it into a single, simpler statement:
```lua
local var = foo() or return false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't compose with multrets.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not? As far as I can tell, the only possible reason it wouldn't is if commas were used somewhere else in the expression, which is solved by using a pair of parentheses.

@alexmccord
Copy link
Contributor

or break could work but or continue won't work, which is an unfortunate problem that argues against this design.


`or return` can be implemented as a binary operation with an optional right side, returning `nil` if no value is given.

The parsing step would be fairly simple as well. Since the new syntax is a way to express an already-supported feature more concisely, it can be transformed back into its original form in the parser. This means no changes are necessitated on the compiler side. If specified in the middle of an expression, it can temporarily store the value on its left side to perform the nil check, then compute the rest of the expression using the original copy. For example,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parser can't rewrite the AST beyond its local context, so AST changes are required for this feature to work.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's understandable. Is there some form of AST expansion/lowering pass that this could fit into, or would this need to be supported in the compiler as well?

@ctrlaltmilk
Copy link
Author

Would or break also make sense? I wonder if we could just allow return and break in expressions where they would otherwise make sense.

I did consider allowing return and break as expressions, but decided that would lead to confusing edge cases when called from a context where those statements wouldn't apply.

@dphfox
Copy link

dphfox commented Aug 28, 2024

Here's an idea, or else.

local humanoid = partParent:FindFirstChild("Humanoid") or else return

It's never valid Luau to have the or keyword before an else keyword, so that sequence should be easy enough to detect. That would then allow proper support for or else continue.

And hey, it reads like posh English, that's fun too :)

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

Successfully merging this pull request may close these issues.

4 participants