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 an infinite-loop construct #1906

Closed
catamorphism opened this issue Feb 26, 2012 · 17 comments
Closed

Add an infinite-loop construct #1906

catamorphism opened this issue Feb 26, 2012 · 17 comments
Labels
C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.

Comments

@catamorphism
Copy link
Contributor

This idea has come up before, but #1905 reminded me that we never really reached agreement on it. I propose adding a new looping construct, forever [block], that has the same semantics as while (true) [block]. The reason to add a special construct would be to allow typestate to recognize that infinite loops run forever, and not yield spurious-looking errors (see #1905 for an example) about functions not returning a value. The current workaround is to do while (true) { ... }; fail "Unreachable";, which isn't terribly burdensome, but is annoying.

I realize we're trying not to add stuff, but this issue seems to be a source of confusion, and while (true) loops seem to be pretty common.

@jruderman
Copy link
Contributor

It might be simpler to have typestate recognize while true as something special.

@brson
Copy link
Contributor

brson commented Feb 26, 2012

Could possibly also make an iterator like fn until<T>(f: fn() -> option<T>) -> T that iterates until the block returns some.

That would at least cover the case in the referenced issue.

@brson
Copy link
Contributor

brson commented Feb 26, 2012

Well, I guess there are lots of ways to structure the code in the other issue so that it isn't a while true loop. I am not in favor of adding a new language construct for this. If they have to write it in a different way anyway then it should be written with a library iterator. Otherwise, I agree with Jesse that while true should interact with typestate in the way that most people intend.

@brson
Copy link
Contributor

brson commented Feb 26, 2012

We could also have do { } just mean 'iterate forever'. At least that doesn't add more keywords.

@brson
Copy link
Contributor

brson commented Feb 26, 2012

Or change do to repeat, so you can have repeat { } mean 'iterate forever', and repeat { } while something; mean 'iterate until'. repeat is clearer that it's a loop.

@pcwalton
Copy link
Contributor

Java's typestate knows about while (true). It's actually rather tricky, because it makes the typestate algorithm have to track booleans. Special-casing the construct while true, and no other, might work, but if it turns out to be difficult in practice it may well be worth adding a new language construct.

@nikomatsakis
Copy link
Contributor

I think it'd be ok to just accept "while true" as our "infinite loop" form, personally.

@graydon
Copy link
Contributor

graydon commented Feb 29, 2012

What's wrong with a library function?

fn forever(body: fn()) -> ! { while true { f(); } core::unreachable(); }

@nikomatsakis
Copy link
Contributor

for one thing, most "infinite" loops actually break... or at least ret. but even if we had break and non-local return, wouldn't type state then have to treat the "forever" library function as special, so as to know that it never returns unless the body breaks?

@graydon
Copy link
Contributor

graydon commented Feb 29, 2012

If it breaks, it's not a forever loop, and this whole bug doesn't apply: the control paths after the loop are reachable.

@nikomatsakis
Copy link
Contributor

It was more ret than break that I was concerned about.

@graydon
Copy link
Contributor

graydon commented Feb 29, 2012

Oh, right. Ok, then in that case you would have to manually put in the ::unreachable() call.

I looked through the compiler and libraries and see ... a few cases, but only a handful. I guess it's a real case; and given that the cost of "solving" it is extremely low in terms of cognitive burden I won't resist further. I'd say I like brson's suggestion of making the trailing while optional, but I think it leads to grammatical ambiguity if you juxtapose it with another while loop. We could make that grammatically illegal, but that's teaching the parser an unusual amount about control flow (nothing can come after a repeat { ... } loop?) and feels like trying to make two wrongs into a right.

If we solve this "in the language" I've a slight preference for an unadorned loop { ... } construct (and hey, it's a keyword in Sather). The word forever is misleading (especially if we usually ret, which we do) and too long anyways. I agree we could get to the same place teaching typestate about while true, but suspect people will be filing followup bugs asking us why we can't tell that while a == b || a != b { ... } is also an "infinite loop", and why don't we include a general boolean solver, and what kind of amateurs are we? I don't want to play that game.

@catamorphism
Copy link
Contributor Author

forever was just a strawperson; loop is good. Maybe we can talk about this at the next Tuesday meeting?

@catamorphism
Copy link
Contributor Author

I'm hearing consensus in the meeting in favor of adding loop, which I will implement.

@graydon
Copy link
Contributor

graydon commented Mar 6, 2012

At meeting, has consensus to implement loop.

catamorphism added a commit that referenced this issue Mar 10, 2012
Add a loop {} construct for infinite loops, and use it in test
cases. See #1906 for details.
@catamorphism
Copy link
Contributor Author

Implemented. Cleanup of existing code-that-uses-while-true is in 35400e1

@graydon
Copy link
Contributor

graydon commented Mar 11, 2012

Great, thanks!

@catamorphism catamorphism removed their assignment Jun 16, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
Projects
None yet
Development

No branches or pull requests

6 participants