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

Improving "leftover constraints" errors #31

Open
zilinc opened this issue Nov 19, 2016 · 26 comments
Open

Improving "leftover constraints" errors #31

zilinc opened this issue Nov 19, 2016 · 26 comments

Comments

@zilinc
Copy link

zilinc commented Nov 19, 2016

No guessing in variant types. For more details see discussions below. Symptom: left-over constraints with an Exhaustive constraint. We might want to enhance it in some future.

zilinc pushed a commit that referenced this issue Nov 19, 2016
@zilinc zilinc added the bug label Nov 20, 2016
@liamoc
Copy link
Collaborator

liamoc commented Nov 20, 2016

This isn't a bug?

The test case never explicitly states what variant type is wanted. The type checker will not guess it.

@liamoc
Copy link
Collaborator

liamoc commented Nov 20, 2016

A simpler version of the same problem is simply:

f : () -> ()
f _ =
  Success ()
  | Success obj -> ()
  | Error -> ()

@zilinc
Copy link
Author

zilinc commented Nov 20, 2016

Hmmm. I see. If I wrote e -> (store_st, e) in the second pattern it will infer.

@zilinc zilinc added enhancement and removed bug labels Nov 20, 2016
@liamoc
Copy link
Collaborator

liamoc commented Nov 20, 2016

What? e -> e? Nothing to do with it?

@liamoc
Copy link
Collaborator

liamoc commented Nov 20, 2016

The thing is if you write Success obj its type is unknown. It will try and work it out from context, but if you pattern match immediately on it, the only thing it knows is that it should have a Success and an Error alternative and that matching on both of them should be exhaustive.. but there are an infinite number of possible types you could give to Success obj which would satisfy those constraints. One example would be <Success Obj | Error | SomethingElse> take SomethingElse

@zilinc
Copy link
Author

zilinc commented Nov 20, 2016

Ahh, typo. So does it really matter which one it guesses? Any minimal type that doesn't introduce inconsistency should be ok for this purpose?

@liamoc
Copy link
Collaborator

liamoc commented Nov 20, 2016

Guessing will introduce really strange results. Remember that <Success Obj> is now not a subtype of <Success Obj | Error>. Guessing a minimal type will give annoying errors like that, unless you do some sort of global guessing based on the entire constraint graph.

@zilinc
Copy link
Author

zilinc commented Nov 20, 2016

Quite annoying --- is there a way to generate a meaningful error message for that?

@zilinc zilinc changed the title leftover constraints No guessing in variant types Nov 20, 2016
@liamoc
Copy link
Collaborator

liamoc commented Nov 20, 2016

Well, if there is a leftover constraint like Exhaustive ?x [....] then that means you're pattern matching on an unknown type and that's going to need a signature somewhere. So we could emit special errors for that case.

Alternatively I could try do to some sort of guesswork -- it would work out okay if you take the entire constraint system into account. But it really feels like it should at least generate a warning if it's doing that. For example, if you have a bunch of code:

 let r =  .... blah blah...
      | some case -> First ()
      | some other case -> First ()
 in r
  | First x -> ....
  | _ -> ....

Then the minimal "guess" would be that the type is just <First ()>, but this would mean that the entire second branch is just dead code -- almost certainly a mistake..

@liamoc
Copy link
Collaborator

liamoc commented Nov 20, 2016

Did this error actually come up in Bilby? Is it easy to add a type signature to it?

@zilinc
Copy link
Author

zilinc commented Nov 20, 2016

In that case you mentioned, it makes sense to emit an error -- if you don't say what the type is, you cannot do _ in patter matching.

@zilinc
Copy link
Author

zilinc commented Nov 20, 2016

It's extracted from bilby. It's possible to add some annotation but in general, the patterns could be large (consequently the types) and with several levels of pattern matching, it requires quite a bit of thinking to understand where guidance is required. Pattern matching is a big feature in FP and it would resist user to write idiomatic functional-style code in Cogent.

@liamoc
Copy link
Collaborator

liamoc commented Nov 20, 2016

Thinking about it more, I don't think we can safely guess.

If we have a constraint Exhaustive ?x [Success a, Error] then if we're guessing we'll just transform that to ?x :< <Success ?y | Error>. Seems fine, right?

The problem is that we only want to guess if there isn't an obvious solution for ?x that doesn't require guessing. Otherwise the "guessed" solution would override the "real" solution. But, if we delay introducing the guess constraint, then that delay could mean that other variables are solved without benefit of information learned from the guess constraint and we'd end up with issue #22 style bugs all over again, but only in rare, hard-to-debug cases.

One little trick to make things easier is to make a constructor function that specifies the type, e.g:

success : all (a,b). a -> R a b
success a = Success a

Then use success instead of Success and your errors should be gone ;)

@zilinc
Copy link
Author

zilinc commented Nov 20, 2016

Looks like a fare trick. After applying that trick, I still got lots of leftovers, which does NOT consist of loops or exhaustive constraints. I need to study more on the original code in order to tell what's going on.
All the leftover constraints are as below: (* indicate reflexive >: relation)

144 >: 2344* >: 2342 >: 2340 >: 2338 >: 58*
                  |       |
                  |       +--------- >: 103*
                  +------ >: 124* 

SomeConcreteType :> 144!           Share 144!

@liamoc
Copy link
Collaborator

liamoc commented Nov 20, 2016

It looks like this might be another situation where they misused !. Note that if ?144 wasn't banged it'd work just fine.

Also, that's a lot of unification variables...

@zilinc
Copy link
Author

zilinc commented Nov 20, 2016

Not sure that's the case, as pass_ticket_e31.cognet also suffers from the same problem.

@zilinc zilinc changed the title No guessing in variant types Leftover constraints Nov 20, 2016
@zilinc zilinc added bug and removed enhancement labels Nov 20, 2016
zilinc pushed a commit that referenced this issue Jan 12, 2017
@zilinc zilinc reopened this Jan 17, 2017
zilinc pushed a commit that referenced this issue Jan 19, 2017
reenable tc test in ci
zilinc pushed a commit that referenced this issue Jan 19, 2017
* compiler: wip - allow type annotations on exprs

[skip ci] it won't pass!

* compiler: mostly working now

* cogent: use type annotation for #31.

reenable tc test in ci
zilinc pushed a commit that referenced this issue Jan 11, 2018
zilinc pushed a commit that referenced this issue Jan 11, 2018
zilinc pushed a commit that referenced this issue Jan 11, 2018
* compiler: wip - allow type annotations on exprs

[skip ci] it won't pass!

* compiler: mostly working now

* cogent: use type annotation for #31.

reenable tc test in ci
zilinc pushed a commit that referenced this issue Jan 22, 2018
zilinc pushed a commit that referenced this issue Jan 22, 2018
zilinc pushed a commit that referenced this issue Jan 22, 2018
* compiler: wip - allow type annotations on exprs

[skip ci] it won't pass!

* compiler: mostly working now

* cogent: use type annotation for #31.

reenable tc test in ci
zilinc pushed a commit that referenced this issue Mar 6, 2018
zilinc pushed a commit that referenced this issue Mar 6, 2018
zilinc pushed a commit that referenced this issue Mar 6, 2018
zilinc pushed a commit that referenced this issue Mar 6, 2018
zilinc pushed a commit that referenced this issue Mar 6, 2018
* compiler: wip - allow type annotations on exprs

[skip ci] it won't pass!

* compiler: mostly working now

* cogent: use type annotation for #31.

reenable tc test in ci
@zilinc zilinc added the story label Sep 10, 2018
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