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

Why are missing free variables not detected at compile time? #89

Closed
tomjaguarpaw opened this issue Aug 6, 2016 · 6 comments
Closed

Comments

@tomjaguarpaw
Copy link

I tried the following program:

partialApply :: Program
partialApply = mconcat
    [ Stg.add
    , [program|
    main = \ => let one   = \ -> Int# 1#;
                    plus1 = \x -> add x one
                in plus1 one
    |]]

It compiled and ran, ending with

7. Errorenous state: one not in scope

I should have written

plus1 = \(one) x -> add x one

Why was this not detected at compile time?

@tomjaguarpaw
Copy link
Author

Actually, plus1 = \(one) x -> add x one doesn't seem to fix it. Can you tell me what's wrong with this program?

@tomjaguarpaw
Copy link
Author

I had to do

partialApply :: Program
partialApply = mconcat
    [ Stg.add
    , [program|
    main = \ => let one   = \ -> Int# 1#
                    in let plus1 = \(one) x -> add x one
                       in  plus1 one
    |]]

This seems to be a consequence of "Like letrec, but the bindings cannot refer to each other (or themselves). In other words, let is non-recursive." (from the README). But shouldn't this be enforced at compile time?

@quchen
Copy link
Owner

quchen commented Aug 9, 2016

Why was this not detected at compile time?

For two reasons,

  1. STGi does not compile anything, it just takes the syntax tree as generated by the parser and puts it into the automaton
  2. The only static analysis that is done (right now) is by the parser, who catches some minor mistakes such as updatable closures that don’t make any sense, as noted in your other ticket Confusing error: "Standard constructors are never updatable, expected: atom (variable or literal)" #88.

As for how to write your program, I would use a letrec.

add = ... -- Prelude
main = \ => 
    letrec 
        one   = \ -> Int# 1#;
        plus1 = \(one) x -> add x one
    in plus1 one

I’ve tried building some better static analysis a couple of times, but it’s not as trivial as I initially thought. I have a long-standing ticket open for reporting unused globals, #23, and a branch that works on that issue (static-analysis it’s called I believe).

@tomjaguarpaw
Copy link
Author

Thanks, I like your letrec version. Static analysis to detect these errors would be good and will have a look at your branch when I get the time.

@quchen
Copy link
Owner

quchen commented Aug 10, 2016

Is there anything else I can help you with? Otherwise I’ll close the ticket.

@tomjaguarpaw
Copy link
Author

That's fine. You can close this one if you like.

@quchen quchen closed this as completed Aug 10, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants