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

Add infinity pattern #1796

Closed
wants to merge 1 commit into from
Closed

Add infinity pattern #1796

wants to merge 1 commit into from

Conversation

ksss
Copy link
Collaborator

@ksss ksss commented Apr 9, 2024

Add a pattern to Array#cycle that returns an Enumerator that loops infinitely, as it is missing.

Whether it loops infinitely or not depends on the receiver and cannot be isolated by overloading.

[1,2,3].cycle.each {} # Return type should be `bot` since it will never return

[].cycle.each {} # Just return `nil`

@soutaro
Copy link
Member

soutaro commented Apr 15, 2024

@ksss I'm not sure if adding the bot case here. We don't have bot type with IO#gets while it doesn't return when the stream is closed. (I'm curious if having it improves something, and open to have it if it does.)

@soutaro soutaro added this to the RBS 3.5 milestone Apr 15, 2024
@ksss
Copy link
Collaborator Author

ksss commented Apr 15, 2024

The key point of this issue is that it's not about bot itself, but about the type argument.
There is no way to write a test case for [1,2,3].cycle despite it having a return value.

assert_send_type(
  "() -> Enumerator[untyped, untyped]",
  [1,2,3], :cycle
)
# Failure: test_cycle(ArrayInstanceTest):
#   Call trace does not match with given method type: #<struct RBS::Test::CallTrace method_name=:cycle, method_call=<RBS::Test::ArgumentsReturn:@arguments: [], @exit_value: #<Enumerator: [1, 2, 3]:cycle>, @exit_type: :return>, block_calls=[], block_given=false>.
#   <["[Array#cycle] ReturnTypeError: expected `Enumerator[untyped, untyped]` but returns `#<Enumerator: [1, 2, 3]:cycle>`"]> was expected to be empty.

Another perspective is that infinite loops can be a critical issue for applications. If programmers could determine the possibility of infinite loops from type information, they could avoid these problems. If it is known that there is a possibility of returning bot, programmers can avoid calling each from Enumerator[untyped, bot].
However, whether this applies to IO#gets is unclear.

@soutaro
Copy link
Member

soutaro commented May 29, 2024

I still don't agree having the Enumerator[.., bot] case makes sense.

  1. A method call may not return doesn't mean we should have bot return type.
  2. We cannot use the two Enumerator union cases. We cannot decompose them with is_a?, and the each return type will be nil | bot, which is technically identical to nil.

@ksss
Copy link
Collaborator Author

ksss commented May 29, 2024

OK make sense!
Thank you for reviewing.

@ksss ksss closed this May 29, 2024
@ksss ksss deleted the array-cycle branch May 29, 2024 12:28
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.

None yet

2 participants