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

Runtime error with recursive definitions #1591

Closed
evancz opened this Issue May 9, 2017 · 2 comments

Comments

Projects
None yet
1 participant
@evancz
Member

evancz commented May 9, 2017

When writing mutually recursive definitions, it is possible to end up with runtime errors. This is most common with complex Decoder or Parser definitions, and can often be resolved by introducing Decode.lazy or Parser.lazy to delay evaluation of certain things.

Good Examples: #1516, #1527, #1529

No SSCCE: #1575, #1560 , #1562

Something Else: #1584

Explanation

Thanks to #873, Elm is able to detect certain forms of bad recursion. For example, it can catch the following:

ones = 1 :: ones
n = n + 1

It detects cases when the recursion is unmediated by a lambda. That means Elm cannot detect cases like these:

loop x = loop x
factorialGood n = if n <= 1 then 1 else n * factorialGood (n-1)
factorialBad n = if n <= 1 then 1 else n * factorialBad (n-0)

Some of these functions will loop infinitely and some are fine. The point is that we do not know of a general and efficient strategy that can successfully rule out "bad" recursion more often. If you have a plausible idea, please write it up and share it on elm-dev.

The actual problem in many cases is that there exists a way to define the values, but it is not being used.

Ideas

Issue #1580 proposes a rather elaborate fix, at least as written. Needs to be distilled down.

Aside from that, this problem may be exacerbated by the fact that code gen produces functions in very particular ways to make currying faster.

var f = F2(function(a,b) { ... });

This means that values that use f before the definition will not be able to find f and crash. We can move all function definitions above all value definitions. This may help with some subset of the issues folks are seeing, but it is not a complete solution.

@elm elm locked and limited conversation to collaborators May 9, 2017

@evancz evancz added the meta label May 9, 2017

@evancz evancz changed the title from Runtime error with mutually recursive definitions to Runtime error with recursive definitions May 9, 2017

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz May 16, 2017

Member

This is probably fixed by e2a5157.

I checked some cases of my own, but I have not yet tested the cases listed here. It is very difficult to build the compiler right now, so this is not something it'll be easy for anyone to check on a whim. Putting on my pre-release checklist.

Member

evancz commented May 16, 2017

This is probably fixed by e2a5157.

I checked some cases of my own, but I have not yet tested the cases listed here. It is very difficult to build the compiler right now, so this is not something it'll be easy for anyone to check on a whim. Putting on my pre-release checklist.

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz May 23, 2018

Member

I outlined a more general approach here, and it is implemented in development builds. All of the examples with SSCCE in this thread work with the new code. Hopefully this is the real deal!

Member

evancz commented May 23, 2018

I outlined a more general approach here, and it is implemented in development builds. All of the examples with SSCCE in this thread work with the new code. Hopefully this is the real deal!

@evancz evancz closed this May 23, 2018

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