(I'm again starting a new thread to focus on this issue. It's easier to track that way.)

On Thu, Oct 4, 2012 at 11:40 AM, Simon Peyton-Jones wrote:

There is also the small matter, in this example, of distinguishing which `_' is which. The description works, but you have to think about it. I don't have an immediate and simple solution to this. Perhaps the addition of unique labels (e.g. _$1 _$2). But this is not a major problem. It can even wait until some future development/expansion on TypeHoles.


Just to clarify the "small matter" above, I was proposing a way to reference unnamed holes in the warning messages. This was only to solve the relatively minor problem of visually distinguishing the holes if there are multiple.

I have a proposal.  Someone has already suggested on hackage.haskell.org/trac/ghc/ticket/5910 that an un-bound variable behaves like a hole.  Thus, if you say

 

          f x = y

GHC says “Error: y is not in scope”.  But (idea) with -XTypeHoles

 

f x = y

might generate

1.   (renamer) Warning: y is not in scope

2.   (type) Error: Hole “y” has type....

So that’s like a named hole, in effect.   

 

If you say

   f x = 4

GHC warns about the unused binding for x.  But if you say

   f _x = 4

the unused-binding warning is suppressed.  So (idea) if you say

          f x = _y

maybe we can suppress warning (1).  And, voila, named holes.

 

Moreover if you add –fdefer-type-errors you can keep going and run the program.

 

Any comments?  This is pretty easy to do.


I also like the proposal; however, I think it only makes sense if the set of unbound variables with the same name is treated as referring to the same identifier. This was, after all, the main reason for named holes. Roman expected this, and I think everybody who uses the feature will expect it.

On Fri, Oct 5, 2012 at 9:24 AM, Roman Cheplyaka wrote:
* Roman Cheplyaka [2012-10-05 10:22:23+0300]
> * Simon Peyton-Jones [2012-10-05 07:14:36+0000]
> > | Sounds cool. I would also expect that if you have several occurences of
> > | the same unbound identifier, then it gets a unified type.
> >
> > I thought about this, but I think not. Consider
> >
> > f x1 = _y
> > g x2 = _y
> >
> > Do you want _y and _y to be unified, so that f and g are no longer polymorphic?  I think not.  Any more than the "_" holes we have now are unified.
>
> Do you mean polymorphism in their argument? Why would it go away?
>
> I would expect the functions to get types `a -> c` and `b -> c`
> respectively, and `c` to be reported as the type of the hole.

Ah, I see. Since `c` is universally quantified, it means different
things for f and g. Good point.

I would expect `_y' to be unified. I'm not sure how to write the type of `f' or `g' (maybe `forall a. a -> c' and `forall b. b -> c'?), but I would still expect `_y' to have some type `c'. It would be endlessly confusing to have identifiers that look the same but aren't.

Here's a thought that just occurred to me, though I'm not yet sure if it makes sense. Treat all expression identifiers _x as unique but report them as one hole with all possible types. Then, you can visually identify the patterns between the types. So:

> f x = _y
> g x = _y 'a'

with some warning like this:

    Found hole `_y' in multiple locations with the possible types
    File.hs:##:##:  a0
    File.hs:##:##:  Char -> b0

Now, I know by looking at it that `a0' and `b0' are universally quantified per location, but I can do some mental unification myself.

Regards,
Sean