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

Function returning partially applied function not compiling in correct order #1360

Closed
joeaulner opened this issue Apr 28, 2016 · 3 comments
Closed

Comments

@joeaulner
Copy link

I am working on an elm project experimenting with parsing, and I have run into an issue while attempting to take advantage of higher order functions.

After building the project and loading it up in the browser I get the following error messages:
image

The error can be traced to the following declarations in the compiled JS:

var feature = A2(block,featureStr,Feature); // error thrown by this call
var block = F4(function (regexStr,token,input,state) {
   var matchLength = $String.length(A2(match,regexStr,input));
   var input$ = A2($String.dropLeft,matchLength,input);
   return A2(tokenize,
   input$,
   _U.update(state,
   {tokens: A2($List._op["::"],token,state.tokens)}));
});

Which is being generated from this file. For some reason feature is being defined prior to block, despite the offending functions not being mutually recursive. This leads me to believe that this is potentially a bug in the compiler.

I know this is a rather large chunk of code, but I was unable to quickly reproduce this in a minimal example. I'll work on getting a minimal reproduction of the error posted here within a reasonable amount of time around my finals.

@joeaulner
Copy link
Author

Another pass through the code had me notice that it is, indeed, a mutually recursive declaration because block calls tokenize, the calling function. Is there anything in the works to provide support for mutually recursive functions in Elm?

@jvoigtlaender
Copy link
Contributor

Is there anything in the works to provide support for mutually recursive functions in Elm?

Mutually recursive functions are supported in Elm.

What is problematic at the moment is recursive values. See #873. It's not completely straightforward where the line is drawn (what's a value, but "not a function"). Basically, it's a question of the syntactic form of the definition. One thing you could try is to reformulate your functions like feature from

feature : (String -> State -> State)
feature = block featureStr Feature

to

feature : (String -> State -> State)
feature string = block featureStr Feature string

May look like it shouldn't make a difference, but absent a fix for #873 it actually can make a difference.

In any case, I don't think what you encountered here is an issue of block and tokenize being mutually recursive. And it's definitely true that Elm does in general support mutually recursive functions. If you need proof:

import Html

even x = if x == 0 then True else odd (x - 1)

odd x = if x == 0 then False else even (x - 1)

main = Html.text (toString (even 13))

@joeaulner
Copy link
Author

Ah, I should have been more thorough in my testing before coming to the conclusion that mutually recursive functions are not supported. Thank you for clearing that up!

I think I now have a better understanding of the difference between a function and a value in Elm. As such, the semantic difference implied by the slight syntactic modification shown in your example makes perfect sense. The behavior of feature is, effectively, left unchanged (as far as the caller knows), but its treatment as a function being applied to a string as opposed to a simple value makes a world of difference to the compiler.

Thanks for the help!

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

2 participants