caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Equality between abstract type definitions
@ 2013-10-24 22:57 Peter Frey
  2013-10-24 23:23 ` Jacques Garrigue
  0 siblings, 1 reply; 27+ messages in thread
From: Peter Frey @ 2013-10-24 22:57 UTC (permalink / raw)
  To: caml-list

Please consider the following two definitions of map which I would have
considered equal.  

  exception Empty

  type 'a t = Cons of 'a * (int -> 'a t) * int

  let null = Cons( Obj.magic None, (fun _ -> assert false), max_int ) 

  let map (f: 'a -> 'b) (t: 'a t) : 'b t =
      if t == null then null else match t with (Cons( h, fn, p )) ->
      let rec aux h1 p1 =
      try match fn p1 with (Cons (h2,_, p2)) -> 
         (Cons(f h1, aux h2, p2 ))
      with Empty                             -> (Cons(f h1, fn, p1)) in
      aux h p

  let map : 'a 'b. ( 'a -> 'b ) -> 'a t -> 'b t = fun f t -> 
    if t == null then null else match t with (Cons( h, fn, p )) ->
    let rec aux h1 p1 =
      try match fn p1 with (Cons (h2,_, p2)) -> (Cons(f h1, aux h2, 2 ))
    with Empty                               -> (Cons(f h1, fn, p1)) in
    aux h p

The second one gives the error below; no surprise.

Error: This definition has type 'b. ('b -> 'b) -> 'b t -> 'b t
       which is less general than 'a 'b. ('a -> 'b) -> 'a t -> 'b t

Why is the first definition accepted?  

Peter Frey




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-24 22:57 [Caml-list] Equality between abstract type definitions Peter Frey
@ 2013-10-24 23:23 ` Jacques Garrigue
  2013-10-25  6:44   ` Andreas Rossberg
  0 siblings, 1 reply; 27+ messages in thread
From: Jacques Garrigue @ 2013-10-24 23:23 UTC (permalink / raw)
  To: Peter Frey; +Cc: OCaML List Mailing

2013/10/25 7:57、Peter Frey <pjfrey@sympatico.ca> のメール:

> Please consider the following two definitions of map which I would have
> considered equal.  
> 
>  exception Empty
> 
>  type 'a t = Cons of 'a * (int -> 'a t) * int
> 
>  let null = Cons( Obj.magic None, (fun _ -> assert false), max_int ) 
> 
>  let map (f: 'a -> 'b) (t: 'a t) : 'b t =
>      if t == null then null else match t with (Cons( h, fn, p )) ->
>      let rec aux h1 p1 =
>      try match fn p1 with (Cons (h2,_, p2)) -> 
>         (Cons(f h1, aux h2, p2 ))
>      with Empty                             -> (Cons(f h1, fn, p1)) in
>      aux h p
> 
>  let map : 'a 'b. ( 'a -> 'b ) -> 'a t -> 'b t = fun f t -> 
>    if t == null then null else match t with (Cons( h, fn, p )) ->
>    let rec aux h1 p1 =
>      try match fn p1 with (Cons (h2,_, p2)) -> (Cons(f h1, aux h2, 2 ))
>    with Empty                               -> (Cons(f h1, fn, p1)) in
>    aux h p
> 
> The second one gives the error below; no surprise.
> 
> Error: This definition has type 'b. ('b -> 'b) -> 'b t -> 'b t
>       which is less general than 'a 'b. ('a -> 'b) -> 'a t -> 'b t
> 
> Why is the first definition accepted?  

Here is the type inferred for the first definition:
val map : ('b -> 'b) -> 'b t -> 'b t = <fun>

As you can see, types for ‘a and ‘b are merged.
In OCaml, type variables used in type annotations are just unification variables:
the type checker is allowed to merge them or instantiate them.
This is useful when you want to indicate that two things have the same type,
without writing the type by hand.
In the second example you use an explicit polymorphic type, which does not
allow instantiating ‘a and ‘b, so you get an error.

Jacques Garrigue

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-24 23:23 ` Jacques Garrigue
@ 2013-10-25  6:44   ` Andreas Rossberg
  2013-10-25  8:29     ` Roberto Di Cosmo
  2013-10-28  3:30     ` Jacques Garrigue
  0 siblings, 2 replies; 27+ messages in thread
From: Andreas Rossberg @ 2013-10-25  6:44 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: OCaML List Mailing

On Oct 25, 2013, at 01:23 , Jacques Garrigue <garrigue@math.nagoya-u.ac.jp> wrote:
> In OCaml, type variables used in type annotations are just unification variables:
> the type checker is allowed to merge them or instantiate them.
> This is useful when you want to indicate that two things have the same type,
> without writing the type by hand.

Jacques, do you think there is any chance that this will ever be changed? I think this keeps being one of the most annoying pitfalls in the OCaml type system, not what most people expect, and in 98% of the cases, not what they want either -- especially since there often is no convenient way to actually express what they want.

A simple proposal, which I'm sure has been made many times before, would be to interpret type variables of the form 'a, 'b as proper universal variables, and only ones of the form '_a, '_b as unification variables. That matches the notation that OCaml has always been using in its output. More expressive and clearer signalling of intent.

Obviously, such a change would break some code, code that actually relies on 'a being just a unification variable. But my optimistic guess is that such code is rather rare. And it would be trivial to adapt.

It would also break code that assumed the wrong behaviour and only compiled by accident (such as the Peter's example). But arguably, that's a good thing, because it uncovers actual bugs.

Anyway, just dreaming aloud… :)

/Andreas


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25  6:44   ` Andreas Rossberg
@ 2013-10-25  8:29     ` Roberto Di Cosmo
  2013-10-25  9:59       ` Ivan Gotovchits
  2013-10-25 14:03       ` Andreas Rossberg
  2013-10-28  3:30     ` Jacques Garrigue
  1 sibling, 2 replies; 27+ messages in thread
From: Roberto Di Cosmo @ 2013-10-25  8:29 UTC (permalink / raw)
  To: Andreas Rossberg; +Cc: Jacques Garrigue, OCaML List Mailing

Dear Andreas,
     let me offer a comment on terminology here: 'a, 'b and the
like have always been used to denote polymorphism in a type, and
hence used as unification variables since the beginning of the ML
language history, to infer the type of a program.

When you annotate a program with types, you are just adding more
type equations to the unification problem, and you may of
course get at the end a type that is less generic than the one
you gave in the annotation (that's the key rule of the game
in unification).

I am curious to know why you consider this a pitfall: if it is
not what people expect, it is probably because nobody explained
their meaning to them properly, and I am quite interested in
understanding how to explain this better.

On the other side, the '_a, '_b variables are just a convenient device that
allows to give a type to programs with side effect when OCaml does not know if
it's safe to apply the generalization rule: a function f of type '_a -> '_a can
be instantiated only once, and after that its type will no longer change
(sometimes these are called "logical" variables, but this terminology is kind of
misleading).  You cannot use '_a variables yourself:

# let f (x: '_a) = x;;
Error: The type variable name '_a is not allowed in programs

--
Roberto

On Fri, Oct 25, 2013 at 08:44:50AM +0200, Andreas Rossberg wrote:
> On Oct 25, 2013, at 01:23 , Jacques Garrigue <garrigue@math.nagoya-u.ac.jp> wrote:
> > In OCaml, type variables used in type annotations are just unification variables:
> > the type checker is allowed to merge them or instantiate them.
> > This is useful when you want to indicate that two things have the same type,
> > without writing the type by hand.
> 
> Jacques, do you think there is any chance that this will ever be changed? I think this keeps being one of the most annoying pitfalls in the OCaml type system, not what most people expect, and in 98% of the cases, not what they want either -- especially since there often is no convenient way to actually express what they want.
> 
> A simple proposal, which I'm sure has been made many times before, would be to interpret type variables of the form 'a, 'b as proper universal variables, and only ones of the form '_a, '_b as unification variables. That matches the notation that OCaml has always been using in its output. More expressive and clearer signalling of intent.
> 
> Obviously, such a change would break some code, code that actually relies on 'a being just a unification variable. But my optimistic guess is that such code is rather rare. And it would be trivial to adapt.
> 
> It would also break code that assumed the wrong behaviour and only compiled by accident (such as the Peter's example). But arguably, that's a good thing, because it uncovers actual bugs.
> 
> Anyway, just dreaming aloud… :)
> 
> /Andreas
> 
> 
> -- 
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

-- 
Roberto Di Cosmo
 
------------------------------------------------------------------
Professeur               En delegation a l'INRIA
PPS                      E-mail: roberto@dicosmo.org
Universite Paris Diderot WWW  : http://www.dicosmo.org
Case 7014                Tel  : ++33-(0)1-57 27 92 20
5, Rue Thomas Mann       
F-75205 Paris Cedex 13   Identica: http://identi.ca/rdicosmo
FRANCE.                  Twitter: http://twitter.com/rdicosmo
------------------------------------------------------------------
Attachments:
MIME accepted, Word deprecated
      http://www.gnu.org/philosophy/no-word-attachments.html
------------------------------------------------------------------
Office location:
 
Bureau 3020 (3rd floor)
Batiment Sophie Germain
Avenue de France
Metro Bibliotheque Francois Mitterrand, ligne 14/RER C
-----------------------------------------------------------------
GPG fingerprint 2931 20CE 3A5A 5390 98EC 8BFC FCCA C3BE 39CB 12D3                        

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25  8:29     ` Roberto Di Cosmo
@ 2013-10-25  9:59       ` Ivan Gotovchits
  2013-10-25 11:09         ` Gabriel Scherer
  2013-10-25 12:35         ` Roberto Di Cosmo
  2013-10-25 14:03       ` Andreas Rossberg
  1 sibling, 2 replies; 27+ messages in thread
From: Ivan Gotovchits @ 2013-10-25  9:59 UTC (permalink / raw)
  To: Roberto Di Cosmo; +Cc: Andreas Rossberg, Jacques Garrigue, OCaML List Mailing

Roberto Di Cosmo <roberto@dicosmo.org> writes:

>
> I am curious to know why you consider this a pitfall: if it is
> not what people expect, it is probably because nobody explained
> their meaning to them properly, and I am quite interested in
> understanding how to explain this better.
>

I think that people expect that an expression:

```
  let a : int = b 
```

is a declaration that value `a` has type int (Just like C'ish 
`int a = b;`). But, indeed, it should be understood as a type
constraint. Thus the following, will be readily accepted by the
type checker (because we «constrain» a to be anything):

```
  let a : 'a = 12
```

The root of misunderstanding, I think, lies in that the same syntax is
used for type annotations and value specifications. Consider the
following example:

```
   module T : sig
    val sum: 'a -> 'a -> 'a
   end = struct
    let sum: 'a -> 'a -> 'a = 
        fun x y -> x + y
   end
```

It looks like that the value sum has the same type in the module
specification and in the module implementation. So if compiler accepts
definition, it should accept that it conforms to the specification. 

Indeed, it's rather intuitional - this types do look the same!

So, I think, that it should be clarified by someone, who knows OCaml and
English much better than me, what is the difference between this two
cases. And it would be great if it will be described in the manual,
too. 




-- 
         (__) 
         (oo) 
   /------\/ 
  / |    ||   
 *  /\---/\ 
    ~~   ~~   
...."Have you mooed today?"...

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25  9:59       ` Ivan Gotovchits
@ 2013-10-25 11:09         ` Gabriel Scherer
  2013-10-25 14:24           ` Andreas Rossberg
  2013-10-25 12:35         ` Roberto Di Cosmo
  1 sibling, 1 reply; 27+ messages in thread
From: Gabriel Scherer @ 2013-10-25 11:09 UTC (permalink / raw)
  To: Ivan Gotovchits
  Cc: Roberto Di Cosmo, Andreas Rossberg, Jacques Garrigue, OCaML List Mailing

[-- Attachment #1: Type: text/plain, Size: 4488 bytes --]

> So, I think, that it should be clarified by someone, who knows OCaml and
> English much better than me, what is the difference between this two
> cases. And it would be great if it will be described in the manual,
>
too.
>

Oh, it is described in the manual:
  http://caml.inria.fr/pub/docs/manual-ocaml-4.01/types.html#typexpr

  In type constraints, [type variables] represent unspecified types
  that can be instantiated by any type to satisfy the type constraint.

The problem is that most people expecting "let x : 'a = 12" to fail did not
(and often will never) read that manual section. Documenting is enough when
people notice they don't know something (and look for the answer). It
doesn't work very well when people guess what something is (so they don't
feel a need to look it up), but consistently guess wrong.

I agree with Andreas that the current situation is unsatisfying, and that
his proposed change would be a net improvement. Roberto says that we should
teach the stuff better, but our constantly-repeated experience is that
people consistently *guess* that type annotations enforce polymorphism --
before seeking for help from teachers on that point. As to why this happen,
I'm not sure (but I don't think we need to have the cause to agree that the
issue requires a change), but I would hazard Ivan's explanation that they
expect that from the meaning of type variables in type signatures, either
inferred in the toplevel or explicitly written in .mli. After all, most
OCaml programs have so few type annotations that people only encounter type
variables in those type signatures. The suggestion to use '_a for flexible
variables seems reasonable.

However, I think that the current syntax of implicitly-introduced variables
with heuristically-defined scoping rules is bad in any case. My own toy
experiment with explicit syntaxes always use an explicit binding syntax for
both rigid and flexible variables (eg. "forall a b c in ..." and "some a b
c in ..."). In this regard, the ('a 'b . ty) or (type a) syntaxes are
definite improvements -- if only we had applied those explicit binding
forms to GADT constructor types as well... So I think that even with
Andreas' proposed change, people would still be surprised by things like
the following:

  let id : 'a -> 'a = fun x -> x

  let dup (x : 'a) ('a * 'a) =
    let result = (x, x) in
    (id : 'a -> 'a) result  (* fails, while (id : 'b -> 'b) works *)


On Fri, Oct 25, 2013 at 11:59 AM, Ivan Gotovchits <ivg@ieee.org> wrote:

> Roberto Di Cosmo <roberto@dicosmo.org> writes:
>
> >
> > I am curious to know why you consider this a pitfall: if it is
> > not what people expect, it is probably because nobody explained
> > their meaning to them properly, and I am quite interested in
> > understanding how to explain this better.
> >
>
> I think that people expect that an expression:
>
> ```
>   let a : int = b
> ```
>
> is a declaration that value `a` has type int (Just like C'ish
> `int a = b;`). But, indeed, it should be understood as a type
> constraint. Thus the following, will be readily accepted by the
> type checker (because we «constrain» a to be anything):
>
> ```
>   let a : 'a = 12
> ```
>
> The root of misunderstanding, I think, lies in that the same syntax is
> used for type annotations and value specifications. Consider the
> following example:
>
> ```
>    module T : sig
>     val sum: 'a -> 'a -> 'a
>    end = struct
>     let sum: 'a -> 'a -> 'a =
>         fun x y -> x + y
>    end
> ```
>
> It looks like that the value sum has the same type in the module
> specification and in the module implementation. So if compiler accepts
> definition, it should accept that it conforms to the specification.
>
> Indeed, it's rather intuitional - this types do look the same!
>
> So, I think, that it should be clarified by someone, who knows OCaml and
> English much better than me, what is the difference between this two
> cases. And it would be great if it will be described in the manual,
> too.
>
>
>
>
> --
>          (__)
>          (oo)
>    /------\/
>   / |    ||
>  *  /\---/\
>     ~~   ~~
> ...."Have you mooed today?"...
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>

[-- Attachment #2: Type: text/html, Size: 6019 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25  9:59       ` Ivan Gotovchits
  2013-10-25 11:09         ` Gabriel Scherer
@ 2013-10-25 12:35         ` Roberto Di Cosmo
  2013-10-25 12:45           ` Jonathan Protzenko
  1 sibling, 1 reply; 27+ messages in thread
From: Roberto Di Cosmo @ 2013-10-25 12:35 UTC (permalink / raw)
  To: Ivan Gotovchits; +Cc: Andreas Rossberg, Jacques Garrigue, OCaML List Mailing

Thanks Ivan,
       the potential confusion between type annotations
in the code and type specifications in module interfaces
is a very good point.

Writing

 let f : 'a -> 'a = fun x -> x+1 

will just boil down to defining 

 val f : int -> int = <fun>

On the other side, declaring 

 val f : 'a -> 'a 

in a module signature actually *requires* the implementation
to be at least as generic as 'a -> 'a, so a definition
let f = fun x -> x+1 in the body will not work.

Nevertheless, I would say that the difference is pretty
easy to grasp, as soon as one explains that specifications
are only introduced in modules signatures, with the val
keyword.

One may want to introduce type specifications in the code
like in Haskell, but I am not sure that il will be much
better for newbies... : let's write some code similar
to the above one

succ :: a -> a
succ n = n+1

here is the system's answer

    No instance for (Num a)
      arising from a use of `+'
    In the expression: n + 1
    In an equation for `succ': succ n = n + 1

Is this really more new-user friendly?

--
Roberto

 

On Fri, Oct 25, 2013 at 01:59:26PM +0400, Ivan Gotovchits wrote:
> Roberto Di Cosmo <roberto@dicosmo.org> writes:
> 
> >
> > I am curious to know why you consider this a pitfall: if it is
> > not what people expect, it is probably because nobody explained
> > their meaning to them properly, and I am quite interested in
> > understanding how to explain this better.
> >
> 
> I think that people expect that an expression:
> 
> ```
>   let a : int = b 
> ```
> 
> is a declaration that value `a` has type int (Just like C'ish 
> `int a = b;`). But, indeed, it should be understood as a type
> constraint. Thus the following, will be readily accepted by the
> type checker (because we «constrain» a to be anything):
> 
> ```
>   let a : 'a = 12
> ```
> 
> The root of misunderstanding, I think, lies in that the same syntax is
> used for type annotations and value specifications. Consider the
> following example:
> 
> ```
>    module T : sig
>     val sum: 'a -> 'a -> 'a
>    end = struct
>     let sum: 'a -> 'a -> 'a = 
>         fun x y -> x + y
>    end
> ```
> 
> It looks like that the value sum has the same type in the module
> specification and in the module implementation. So if compiler accepts
> definition, it should accept that it conforms to the specification. 
> 
> Indeed, it's rather intuitional - this types do look the same!
> 
> So, I think, that it should be clarified by someone, who knows OCaml and
> English much better than me, what is the difference between this two
> cases. And it would be great if it will be described in the manual,
> too. 
> 
> 
> 
> 
> -- 
>          (__) 
>          (oo) 
>    /------\/ 
>   / |    ||   
>  *  /\---/\ 
>     ~~   ~~   
> ...."Have you mooed today?"...

-- 
Roberto Di Cosmo
 
------------------------------------------------------------------
Professeur               En delegation a l'INRIA
PPS                      E-mail: roberto@dicosmo.org
Universite Paris Diderot WWW  : http://www.dicosmo.org
Case 7014                Tel  : ++33-(0)1-57 27 92 20
5, Rue Thomas Mann       
F-75205 Paris Cedex 13   Identica: http://identi.ca/rdicosmo
FRANCE.                  Twitter: http://twitter.com/rdicosmo
------------------------------------------------------------------
Attachments:
MIME accepted, Word deprecated
      http://www.gnu.org/philosophy/no-word-attachments.html
------------------------------------------------------------------
Office location:
 
Bureau 3020 (3rd floor)
Batiment Sophie Germain
Avenue de France
Metro Bibliotheque Francois Mitterrand, ligne 14/RER C
-----------------------------------------------------------------
GPG fingerprint 2931 20CE 3A5A 5390 98EC 8BFC FCCA C3BE 39CB 12D3                        

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25 12:35         ` Roberto Di Cosmo
@ 2013-10-25 12:45           ` Jonathan Protzenko
  2013-10-25 13:20             ` Roberto Di Cosmo
  0 siblings, 1 reply; 27+ messages in thread
From: Jonathan Protzenko @ 2013-10-25 12:45 UTC (permalink / raw)
  To: Roberto Di Cosmo, Ivan Gotovchits
  Cc: Andreas Rossberg, Jacques Garrigue, OCaML List Mailing

On 10/25/2013 02:35 PM, Roberto Di Cosmo wrote:
> Thanks Ivan,
>        the potential confusion between type annotations
> in the code and type specifications in module interfaces
> is a very good point.
>
> Writing
>
>  let f : 'a -> 'a = fun x -> x+1 
>
> will just boil down to defining 
>
>  val f : int -> int = <fun>
>
> On the other side, declaring 
>
>  val f : 'a -> 'a 
>
> in a module signature actually *requires* the implementation
> to be at least as generic as 'a -> 'a, so a definition
> let f = fun x -> x+1 in the body will not work.
You should also remember that the top-level, which is what most
beginners use, also favors the confusion.

# let f x = x;;
val f : 'a -> 'a = <fun>
# let f : 'a -> 'a = fun x -> x + 1;;
val f : int -> int = <fun>

What OCaml is actually telling you is: "this function has type 'a -> 'a,
but if you write 'a -> 'a yourself, I'm going to give it a totally
different meaning".

~ jonathan

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25 12:45           ` Jonathan Protzenko
@ 2013-10-25 13:20             ` Roberto Di Cosmo
  0 siblings, 0 replies; 27+ messages in thread
From: Roberto Di Cosmo @ 2013-10-25 13:20 UTC (permalink / raw)
  To: Jonathan Protzenko
  Cc: Ivan Gotovchits, Andreas Rossberg, Jacques Garrigue, OCaML List Mailing

Hi Jonathan,
   I beg to disagree

On Fri, Oct 25, 2013 at 02:45:52PM +0200, Jonathan Protzenko wrote:
> You should also remember that the top-level, which is what most
> beginners use, also favors the confusion.
> 
> # let f x = x;;
> val f : 'a -> 'a = <fun>

OCaml is telling you: hey, your code is so generic that I can give it
the type 'a -> 'a, you got a polymorphic function!

> # let f : 'a -> 'a = fun x -> x + 1;;
> val f : int -> int = <fun>
> 

Here you are telling OCaml: 
 look, I'd like to see f as having type 'a -> 'a, what do you think?

And OCaml tells you: sorry sir, the best I can give you is int -> int

> What OCaml is actually telling you is: "this function has type 'a -> 'a,
> but if you write 'a -> 'a yourself, I'm going to give it a totally
> different meaning".
> 
> ~ jonathan

The point on which I agree is that if we leave these annotations in
the code, they may end up being read as specifications by whomever
looks at the sources alone, and this may lead to confusion.

But to spot such issues we do not need to change the syntax and semantics of 
type annotations, it would be enough to have yet another warning
that informs us that the type annotations have been instanciated...
something like

# let f : 'a -> 'a = fun x -> x + 1;;
           _______
Warning 66: the user provided type constraint is too general:
variable 'a has been instanciated to type int
val f : int -> int = <fun>

--
Roberto

P.S.: I will not feed the troll any longer though, time to
get back to work :-)


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25  8:29     ` Roberto Di Cosmo
  2013-10-25  9:59       ` Ivan Gotovchits
@ 2013-10-25 14:03       ` Andreas Rossberg
  2013-10-26  9:07         ` oleg
  2013-10-26 17:32         ` Didier Remy
  1 sibling, 2 replies; 27+ messages in thread
From: Andreas Rossberg @ 2013-10-25 14:03 UTC (permalink / raw)
  To: Roberto Di Cosmo; +Cc: Jacques Garrigue, OCaML List Mailing

On 10/25/2013 10:29 AM, Roberto Di Cosmo wrote:
>       let me offer a comment on terminology here: 'a, 'b and the
> like have always been used to denote polymorphism in a type, and
> hence used as unification variables since the beginning of the ML
> language history, to infer the type of a program.

I believe you are mistaken. At least in Standard ML, explicit type 
variables have always been interpreted as quantified variables, not 
unification variables. If you try to write

   fun f(x : 'a) = x + 1

or

   fun g(x : 'a) = x : 'b

that's an error.


> When you annotate a program with types, you are just adding more
> type equations to the unification problem, and you may of
> course get at the end a type that is less generic than the one
> you gave in the annotation (that's the key rule of the game
> in unification).

Aren't you conflating two different universes here? Namely, the 
declarative type system and the type inference algorithm? The ML type 
system semantics as such, at least in most formalisations I can 
remember, knows nothing about unification variables -- that's an 
implementation detail of algorithm W. And the user interface of a 
language is the declarative system, not the underlying implementation. 
Making unification variables user-visible is an extension to the basic 
ML type system that I have rarely seen made precise (I seem to remember 
that the Didiers did that in the context of MLF).

/Andreas


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25 11:09         ` Gabriel Scherer
@ 2013-10-25 14:24           ` Andreas Rossberg
  2013-10-25 20:32             ` Yaron Minsky
  0 siblings, 1 reply; 27+ messages in thread
From: Andreas Rossberg @ 2013-10-25 14:24 UTC (permalink / raw)
  To: Gabriel Scherer, Ivan Gotovchits
  Cc: Roberto Di Cosmo, Jacques Garrigue, OCaML List Mailing

On 10/25/2013 01:09 PM, Gabriel Scherer wrote:
> However, I think that the current syntax of implicitly-introduced
> variables with heuristically-defined scoping rules is bad in any case.
> My own toy experiment with explicit syntaxes always use an explicit
> binding syntax for both rigid and flexible variables (eg. "forall a b c
> in ..." and "some a b c in ..."). In this regard, the ('a 'b . ty) or
> (type a) syntaxes are definite improvements -- if only we had applied
> those explicit binding forms to GADT constructor types as well... So I
> think that even with Andreas' proposed change, people would still be
> surprised by things like the following:
>
>    let id : 'a -> 'a = fun x -> x
>
>    let dup (x : 'a) ('a * 'a) =
>      let result = (x, x) in
>      (id : 'a -> 'a) result  (* fails, while (id : 'b -> 'b) works *)

Yes, I agree that implicit scoping is a bit of an ugly hack. That said, 
I don't expect anybody to be truly surprised about the example above. At 
least I never heard this being an issue for SML programmers. People 
probably hardly ever write anything like the above, or avoid shadowing 
for clarity anyway.

/Andreas


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25 14:24           ` Andreas Rossberg
@ 2013-10-25 20:32             ` Yaron Minsky
  2013-10-25 20:44               ` Jacques Le Normand
  2013-10-27 12:16               ` Andreas Rossberg
  0 siblings, 2 replies; 27+ messages in thread
From: Yaron Minsky @ 2013-10-25 20:32 UTC (permalink / raw)
  To: Andreas Rossberg
  Cc: Gabriel Scherer, Ivan Gotovchits, Roberto Di Cosmo,
	Jacques Garrigue, OCaML List Mailing

Changing the semantics of this will, I think, break a _lot_ of code.
I for one am not excited to do so.

For what it's worth, I suspect that most people who are surprised by
this are people who were trained on Standard ML.  At Jane Street we've
had a lot of people learn the language, and the complaints I've heard
about this feature are, I think, mostly from that group.

I also don't find Andreas suggestion particularly intuitive.  I would
have guessed that (x: '_a) would constrain x to be a weakly
polymorphic value, which is at odds with the proposal.

y

On Fri, Oct 25, 2013 at 10:24 AM, Andreas Rossberg <rossberg@mpi-sws.org> wrote:
> On 10/25/2013 01:09 PM, Gabriel Scherer wrote:
>>
>> However, I think that the current syntax of implicitly-introduced
>> variables with heuristically-defined scoping rules is bad in any case.
>> My own toy experiment with explicit syntaxes always use an explicit
>> binding syntax for both rigid and flexible variables (eg. "forall a b c
>> in ..." and "some a b c in ..."). In this regard, the ('a 'b . ty) or
>> (type a) syntaxes are definite improvements -- if only we had applied
>> those explicit binding forms to GADT constructor types as well... So I
>> think that even with Andreas' proposed change, people would still be
>> surprised by things like the following:
>>
>>    let id : 'a -> 'a = fun x -> x
>>
>>    let dup (x : 'a) ('a * 'a) =
>>      let result = (x, x) in
>>      (id : 'a -> 'a) result  (* fails, while (id : 'b -> 'b) works *)
>
>
> Yes, I agree that implicit scoping is a bit of an ugly hack. That said, I
> don't expect anybody to be truly surprised about the example above. At least
> I never heard this being an issue for SML programmers. People probably
> hardly ever write anything like the above, or avoid shadowing for clarity
> anyway.
>
> /Andreas
>
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25 20:32             ` Yaron Minsky
@ 2013-10-25 20:44               ` Jacques Le Normand
  2013-10-26  1:08                 ` Norman Hardy
  2013-10-27 12:16               ` Andreas Rossberg
  1 sibling, 1 reply; 27+ messages in thread
From: Jacques Le Normand @ 2013-10-25 20:44 UTC (permalink / raw)
  To: Yaron Minsky
  Cc: Andreas Rossberg, Gabriel Scherer, Ivan Gotovchits,
	Roberto Di Cosmo, Jacques Garrigue, OCaML List Mailing

[-- Attachment #1: Type: text/plain, Size: 2586 bytes --]

I'm surprised noone has pointed out the new type annotation syntax:

let id : type s. s -> s = fun x -> x


On Fri, Oct 25, 2013 at 4:32 PM, Yaron Minsky <yminsky@janestreet.com>wrote:

> Changing the semantics of this will, I think, break a _lot_ of code.
> I for one am not excited to do so.
>
> For what it's worth, I suspect that most people who are surprised by
> this are people who were trained on Standard ML.  At Jane Street we've
> had a lot of people learn the language, and the complaints I've heard
> about this feature are, I think, mostly from that group.
>
> I also don't find Andreas suggestion particularly intuitive.  I would
> have guessed that (x: '_a) would constrain x to be a weakly
> polymorphic value, which is at odds with the proposal.
>
> y
>
> On Fri, Oct 25, 2013 at 10:24 AM, Andreas Rossberg <rossberg@mpi-sws.org>
> wrote:
> > On 10/25/2013 01:09 PM, Gabriel Scherer wrote:
> >>
> >> However, I think that the current syntax of implicitly-introduced
> >> variables with heuristically-defined scoping rules is bad in any case.
> >> My own toy experiment with explicit syntaxes always use an explicit
> >> binding syntax for both rigid and flexible variables (eg. "forall a b c
> >> in ..." and "some a b c in ..."). In this regard, the ('a 'b . ty) or
> >> (type a) syntaxes are definite improvements -- if only we had applied
> >> those explicit binding forms to GADT constructor types as well... So I
> >> think that even with Andreas' proposed change, people would still be
> >> surprised by things like the following:
> >>
> >>    let id : 'a -> 'a = fun x -> x
> >>
> >>    let dup (x : 'a) ('a * 'a) =
> >>      let result = (x, x) in
> >>      (id : 'a -> 'a) result  (* fails, while (id : 'b -> 'b) works *)
> >
> >
> > Yes, I agree that implicit scoping is a bit of an ugly hack. That said, I
> > don't expect anybody to be truly surprised about the example above. At
> least
> > I never heard this being an issue for SML programmers. People probably
> > hardly ever write anything like the above, or avoid shadowing for clarity
> > anyway.
> >
> > /Andreas
> >
> >
> >
> > --
> > Caml-list mailing list.  Subscription management and archives:
> > https://sympa.inria.fr/sympa/arc/caml-list
> > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> > Bug reports: http://caml.inria.fr/bin/caml-bugs
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>

[-- Attachment #2: Type: text/html, Size: 3930 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25 20:44               ` Jacques Le Normand
@ 2013-10-26  1:08                 ` Norman Hardy
  2013-10-26  5:28                   ` Jacques Garrigue
  0 siblings, 1 reply; 27+ messages in thread
From: Norman Hardy @ 2013-10-26  1:08 UTC (permalink / raw)
  To: Jacques Le Normand
  Cc: Yaron Minsky, Andreas Rossberg, Gabriel Scherer, Ivan Gotovchits,
	Roberto Di Cosmo, Jacques Garrigue, OCaML List Mailing

[-- Attachment #1: Type: text/plain, Size: 468 bytes --]


On 2013 Oct 25, at 13:44 , Jacques Le Normand <rathereasy@gmail.com> wrote:

> I'm surprised noone has pointed out the new type annotation syntax:
> 
> let id : type s. s -> s = fun x -> x
> 

I like that syntax, I think.
I suppose that "id : type s. s -> s = fun x -> x" is a let-binding
and that "id : type s. s -> s" is a pattern,
but I cannot get the syntax at http://caml.inria.fr/pub/docs/manual-ocaml/patterns.html
to produce "id : type s. s -> s”.

[-- Attachment #2: Type: text/html, Size: 1426 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-26  1:08                 ` Norman Hardy
@ 2013-10-26  5:28                   ` Jacques Garrigue
  0 siblings, 0 replies; 27+ messages in thread
From: Jacques Garrigue @ 2013-10-26  5:28 UTC (permalink / raw)
  To: Norman Hardy; +Cc: Mailing List OCaml

[-- Attachment #1: Type: text/plain, Size: 763 bytes --]

Both explicit polymorphic annotations and the polymorphic syntax of locally
abstract types are extensions.
http://caml.inria.fr/pub/docs/manual-ocaml/extn.html
See subsections 7.12 and 7.13.

Jacques Garrigue
2013/10/26 10:09 "Norman Hardy" <norm@cap-lore.com>:

>
> On 2013 Oct 25, at 13:44 , Jacques Le Normand <rathereasy@gmail.com>
> wrote:
>
> I'm surprised noone has pointed out the new type annotation syntax:
>
> let id : type s. s -> s = fun x -> x
>
>
> I like that syntax, I think.
> I suppose that "id : type s. s -> s = fun x -> x" is a let-binding
> and that "id : type s. s -> s" is a pattern,
> but I cannot get the syntax at
> http://caml.inria.fr/pub/docs/manual-ocaml/patterns.html
> to produce "id : type s. s -> s”.
>

[-- Attachment #2: Type: text/html, Size: 1672 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25 14:03       ` Andreas Rossberg
@ 2013-10-26  9:07         ` oleg
  2013-10-26 14:11           ` Didier Remy
  2013-10-26 17:32         ` Didier Remy
  1 sibling, 1 reply; 27+ messages in thread
From: oleg @ 2013-10-26  9:07 UTC (permalink / raw)
  To: rossberg; +Cc: caml-list, roberto, gabriel.scherer


Perhaps a bit of history may help. In the Haskell compiler GHC, until
version 6 as I recall, type variables in annotations have the same
semantics as presently in OCaml. That is, type variables in Haskell
were all `flexible', with OCaml's scoping rules. When GHC started to
play with GADTs (ca 2006), the semantics of type variables has changed
-- to what Andreas is proposing. That is, type variables became rigid,
like they are in SML. The scoping rules are cleaned up (although
whether the rules became simpler is the subject of a debate -- there are
lots of corner cases to trip the unwary). The changeover from flexible
to rigid did break all code that used type variables in annotations --
including mine. Well, one learns to live with it. It wasn't the first
or the last time when a new version of GHC breaks code. Almost always the
change is for the better. It seems the community prefers acute but
short pain to the dull and prolonged.

> succ :: a -> a
> succ n = n+1
>
> here is the system's answer
>
>     No instance for (Num a)
>       arising from a use of `+'
>     In the expression: n + 1
>     In an equation for `succ': succ n = n + 1
>
> Is this really more new-user friendly?

Perhaps this is a too advanced example for new users. Polymorphic
numerals of Haskell per se are not new-user friendly. One is welcome
to try to explain to new users the following error message:

> *Prelude> 1 + "a"
>
> <interactive>:1163:3:
>     No instance for (Num [Char])
>       arising from a use of `+'
>     Possible fix: add an instance declaration for (Num [Char])
>     In the expression: 1 + "a"
>     In an equation for `it': it = 1 + "a"

And there are people who may be tempted to follow the proposed fix.

In all fairness, although the error message is greatly off-putting to
the new users, the surprise does not last long and people quickly get
past it. It means the education does work. The same education quickly
tells the users the problem with the original succ example: the
type inferred typed turns out not as general as the type specified
in the annotation. The type variable cannot be quantified without
constraints: the Num a constraint should be added. A better example

    foo :: a -> a
    foo = not

        Couldn't match type `a' with `Bool'
          `a' is a rigid type variable bound by
              the type signature for foo :: a -> a at <interactive>:1165:20
        Expected type: a -> a
          Actual type: Bool -> Bool
        In the expression: not
        In an equation for `foo': foo = not

gives a much more understandable error message, even to new users. GHC
error messages are generally very good: note how the error message
tells where the type variable is bound.

Since all type variables in Haskell are rigid, there is no longer any
convenient way to tell GHC that I think two sub-expression in a large
definition should have the same type. That's a pity. OCaml's type
variables are great for that. OCaml type variables can be understood
purely declaratively, as an assertion from the programmer that all
sub-expressions marked by the same type variables must have the same
type, whatever it turns out to be. I often feel the need for such
annotations in Haskell. There are workarounds, but they are ugly.

My own suggestion is to make clear that type variables in the 'val'
declarations are universally quantified. That is, the inferred type
of 
        let foo = fun x -> x
should be printed as
        val foo : 'a. 'a -> 'a
Likewise, such syntax should be encouraged for val declarations in
modules (omitting the quantifier "'a ." should also be acceptable for
val declarations, perhaps prompting a warning).




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-26  9:07         ` oleg
@ 2013-10-26 14:11           ` Didier Remy
  0 siblings, 0 replies; 27+ messages in thread
From: Didier Remy @ 2013-10-26 14:11 UTC (permalink / raw)
  To: caml-list

> Since all type variables in Haskell are rigid, there is no longer any
> convenient way to tell GHC that I think two sub-expression in a large
> definition should have the same type. That's a pity. OCaml's type
> variables are great for that. OCaml type variables can be understood
> purely declaratively, as an assertion from the programmer that all
> sub-expressions marked by the same type variables must have the same
> type, whatever it turns out to be. I often feel the need for such
> annotations in Haskell. There are workarounds, but they are ugly.

Indeed, both forms are useful, since in a system that does type inferenece I
may wish to specify part of the annotations but not all of it.  Rigid
variables will make the type checker complain if the inferred type is weaker
than what I expected and flexible variables allow me to omit parts of types
that I don't care about or just say that two parts of a type should be the
same without caring what these parts exactly are.

    For example, one should be able to express annotations of the form:

        for all 'a, 'b, for some 'u, ('a -> 'b) -> 'a * 'u -> 'b * 'u

    where 'u, 'v are flexible but 'a, 'b are rigid.

    Bindings should not just be in a single type annotations but in programs,
    so that two arguments can for instance be requested to have the same type.

        let g =
            let f (for some 'a) (x : 'a) (y : 'a) = ... in
        in ...

    Notice, that the inner binding has a limited scope,  which allows
    variables that will appear in the type inferred for 'a to be generalized
    in the type of f.

In fact, now that existential variables have been introduced in the
language, via local modules or gadts, there are three kinds of bindings:
rigid (universal or existential) and flexible variables. Even though
universal and existential are treated in the same way as rigid variables
which cannot be instantiated, their meaning is different and we should
probaly reflect this by a syntactic difference.

Hence, a good design (if we were to redo it from scratch) should require the
user to always explicitly bind type variables, forcing him to say how and
were there are bound.

     Didier


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25 14:03       ` Andreas Rossberg
  2013-10-26  9:07         ` oleg
@ 2013-10-26 17:32         ` Didier Remy
  2013-10-27 12:07           ` Andreas Rossberg
  1 sibling, 1 reply; 27+ messages in thread
From: Didier Remy @ 2013-10-26 17:32 UTC (permalink / raw)
  To: caml-list, Francois Pottier

>> When you annotate a program with types, you are just adding more
>> type equations to the unification problem, and you may of
>> course get at the end a type that is less generic than the one
>> you gave in the annotation (that's the key rule of the game
>> in unification).

> Aren't you conflating two different universes here? Namely, the
> declarative type system and the type inference algorithm? The ML type
> system semantics as such, at least in most formalisations I can remember,
> knows nothing about unification variables -- that's an implementation
> detail of algorithm W. And the user interface of a language is the
> declarative system, not the underlying implementation. Making unification
> variables user-visible is an extension to the basic ML type system that I
> have rarely seen made precise

Andreas, I am not sure what point you are trying to make.

Sure, the name "unification variable" is misleading and should not be used
here, as it refers to the algorithm. Instead, one should call them flexible
type variable or whatever that refers to the specification.

Still, flexible variables make a lot of sense in the specification (even
if not often done in formal presentations).

A language that does type inference should allow the user to say that two
arguments have the same type without telling what these types are, using a
flexible type variable.  (It should also allow the user to tell the type
checker that some expression whould have exactly this type scheme, using a
rigid type variable.

For this reason, the language should expose to the user the both notions of
rigid and flexible bindings.

One can easily specify the introduction of a flexible variable 'a in some
program M as the following typing rule and without reference to the
implementation:

                           G |- M ['a <- t] : s
                           -----------------------
                           G |- for some 'a. M : s

François and I discuss this and formalize it in our chapter "The Essence of
ML Type Inference" in "Advanced Topics in Types and Programming".

----------------

> (I seem to remember that the Didiers did that in the context of MLF).

Yes, since we needed more annotations in MLF because all function paramters
that are used polymorphically must be annotated, we wanted to be able to
only annoatte specify parts of the parameter that had to be used
polymorphically.  We could give type annotations of the form:

         for some 'u, for all 'a, 'b, ('a -> 'b) -> 'a * 'u -> 'b * 'v

When used as the annotation of a function parameter, 'u could be freely
instantiated, even to a polymorphic type, as long as this part of the
argument was not used polymorphically.

We found this necessary in MLF, but it would also be quite useful in OCaml.

         Didier

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-26 17:32         ` Didier Remy
@ 2013-10-27 12:07           ` Andreas Rossberg
  2013-10-27 14:10             ` Roberto Di Cosmo
  0 siblings, 1 reply; 27+ messages in thread
From: Andreas Rossberg @ 2013-10-27 12:07 UTC (permalink / raw)
  To: Didier.Remy; +Cc: caml-list, Francois Pottier

On Oct 26, 2013, at 19:32 , Didier Remy <Didier.Remy@inria.fr> wrote:
>>> When you annotate a program with types, you are just adding more
>>> type equations to the unification problem, and you may of
>>> course get at the end a type that is less generic than the one
>>> you gave in the annotation (that's the key rule of the game
>>> in unification).
> 
>> Aren't you conflating two different universes here? Namely, the
>> declarative type system and the type inference algorithm? The ML type
>> system semantics as such, at least in most formalisations I can remember,
>> knows nothing about unification variables -- that's an implementation
>> detail of algorithm W. And the user interface of a language is the
>> declarative system, not the underlying implementation. Making unification
>> variables user-visible is an extension to the basic ML type system that I
>> have rarely seen made precise
> 
> Andreas, I am not sure what point you are trying to make.
> 
> Sure, the name "unification variable" is misleading and should not be used
> here, as it refers to the algorithm. Instead, one should call them flexible
> type variable or whatever that refers to the specification.
> 
> Still, flexible variables make a lot of sense in the specification (even
> if not often done in formal presentations).

Oh, I agree. I was merely questioning that all explicit type variables in ML would naturally be flexible variables, which was what I was reading into Roberto's reply (if you take the preceding paragraph from his post as context). Sure, flexible variables are easy (and useful) to add, but technically speaking they are an extension, i.e., require extra rules. Or would you not say so?

And yes, I want to have both forms of variables/bindings, as I suggested in my original post. My main concern with the current state of affairs in OCaml is that implicitly interpreting 'a as the flexible kind obviously is surprising to many people, arguably because it is somewhat inconsistent. Especially when rigid probably is the more common use case.


> One can easily specify the introduction of a flexible variable 'a in some
> program M as the following typing rule and without reference to the
> implementation:
> 
>                          G |- M ['a <- t] : s
>                          -----------------------
>                          G |- for some 'a. M : s
> 
> François and I discuss this and formalize it in our chapter "The Essence of
> ML Type Inference" in "Advanced Topics in Types and Programming".

Ah, yes, thanks for the reminder.


>> (I seem to remember that the Didiers did that in the context of MLF).
> 
> Yes, since we needed more annotations in MLF because all function paramters
> that are used polymorphically must be annotated, we wanted to be able to
> only annoatte specify parts of the parameter that had to be used
> polymorphically.  We could give type annotations of the form:
> 
>        for some 'u, for all 'a, 'b, ('a -> 'b) -> 'a * 'u -> 'b * 'v
> 
> When used as the annotation of a function parameter, 'u could be freely
> instantiated, even to a polymorphic type, as long as this part of the
> argument was not used polymorphically.
> 
> We found this necessary in MLF, but it would also be quite useful in OCaml.


Yes, makes sense. I suppose the main obstacle is retrofitting a nice syntax into OCaml.

/Andreas


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25 20:32             ` Yaron Minsky
  2013-10-25 20:44               ` Jacques Le Normand
@ 2013-10-27 12:16               ` Andreas Rossberg
  2013-10-27 12:56                 ` Yaron Minsky
  1 sibling, 1 reply; 27+ messages in thread
From: Andreas Rossberg @ 2013-10-27 12:16 UTC (permalink / raw)
  To: Yaron Minsky; +Cc: OCaML List Mailing

On Oct 25, 2013, at 22:32 , Yaron Minsky <yminsky@janestreet.com> wrote:
> Changing the semantics of this will, I think, break a _lot_ of code.

Interesting. Do you have specific examples in mind?

> For what it's worth, I suspect that most people who are surprised by
> this are people who were trained on Standard ML.  At Jane Street we've
> had a lot of people learn the language, and the complaints I've heard
> about this feature are, I think, mostly from that group.

Maybe, but it's not my impression that this is true for most people I see asking related questions here on the list or on SO.

> I also don't find Andreas suggestion particularly intuitive.  I would
> have guessed that (x: '_a) would constrain x to be a weakly
> polymorphic value, which is at odds with the proposal.

Now, _that_ is something I would only expect from programmers trained on SML -- ancient SML'90 to be precise. ;)

Note how OCaml already uses '_a for a sort of flexible variable in its output.

/Andreas


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-27 12:16               ` Andreas Rossberg
@ 2013-10-27 12:56                 ` Yaron Minsky
  2013-10-27 14:28                   ` Gabriel Scherer
  0 siblings, 1 reply; 27+ messages in thread
From: Yaron Minsky @ 2013-10-27 12:56 UTC (permalink / raw)
  To: Andreas Rossberg; +Cc: OCaML List Mailing

On Sun, Oct 27, 2013 at 8:16 AM, Andreas Rossberg <rossberg@mpi-sws.org> wrote:
> On Oct 25, 2013, at 22:32 , Yaron Minsky <yminsky@janestreet.com> wrote:
>> Changing the semantics of this will, I think, break a _lot_ of code.
>
> Interesting. Do you have specific examples in mind?

I know that I've seen many examples come up in my code.  One common
use is to partially specify a type.  For example, if I wanted to
ignore a return value that is a Tcp.Server.t from Async, I would
probably write it like this:

    (ignore server : ('a,'b) Tcp.Server.t)

without specifying the sometimes rather complicated details of those
types.  Similarly, if I were to ignore a Map, I might write

    (ignore map : (int,string,'a) Map.t

since it's not helpful here to specify the comparator type, which is
what goes into the third slot here.

Nowadays, I would probably use an underscore in these cases rather
than an explicit type variable, but our codebase has plenty of old
examples of this kind of thing.  If a change like the one you propose
is changed, I presume that _ would keep its current meeting, which
would address many use cases.

Given the existence of such use-cases, I would hope that we could
avoid making the change in a way that would non-optionally break lots
of code.  If people agree this change should be made, perhaps it
should be done in the mode of -strict-sequence.  That change was added
as a flag, so users could take it at their own pace.

>> For what it's worth, I suspect that most people who are surprised by
>> this are people who were trained on Standard ML.  At Jane Street we've
>> had a lot of people learn the language, and the complaints I've heard
>> about this feature are, I think, mostly from that group.
>
> Maybe, but it's not my impression that this is true for most people I see asking related questions here on the list or on SO.

To be clear, my guess above is less than scientific.

>> I also don't find Andreas suggestion particularly intuitive.  I would
>> have guessed that (x: '_a) would constrain x to be a weakly
>> polymorphic value, which is at odds with the proposal.
>
> Now, _that_ is something I would only expect from programmers trained on SML -- ancient SML'90 to be precise. ;)
>
> Note how OCaml already uses '_a for a sort of flexible variable in its output.

Where?

> /Andreas
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-27 12:07           ` Andreas Rossberg
@ 2013-10-27 14:10             ` Roberto Di Cosmo
  0 siblings, 0 replies; 27+ messages in thread
From: Roberto Di Cosmo @ 2013-10-27 14:10 UTC (permalink / raw)
  To: Andreas Rossberg; +Cc: Didier.Remy, caml-list, Francois Pottier

Wow, I did not expect to be spawning such a long exchange with my
request of information on what appears surprising in type annotations
as they are used today in OCaml, but all in all, I don't regret it,
as it brought up a lot of useful information, that I'll refrain from
summarising here: I just want to thank sincerely everybody for all the
comments, as I actually ended up learning a lot here, and I believe
I am not alone.

Let me offer, though, a general comment which goes beyond the specific scope of
this thread: of course incompatible changes to a language can be done, and
have been regularly done in the past of our preferred language, with the
wonderful CamlLight/CSL/OCaml team providing auto-magic converters that
reduced somehow the pain of the transition.

But I believe that such changes should only be made after a very careful
and thorough consideration of their advantages and impact: it cannot just
be motivated by the fact that a part of the user community finds a certain
notation more or less intuitive than another, as another part of the
community may feel exactly the opposite.

-- 
Roberto
 
------------------------------------------------------------------
Professeur               En delegation a l'INRIA
PPS                      E-mail: roberto@dicosmo.org
Universite Paris Diderot WWW  : http://www.dicosmo.org
Case 7014                Tel  : ++33-(0)1-57 27 92 20
5, Rue Thomas Mann       
F-75205 Paris Cedex 13   Identica: http://identi.ca/rdicosmo
FRANCE.                  Twitter: http://twitter.com/rdicosmo
------------------------------------------------------------------
Attachments:
MIME accepted, Word deprecated
      http://www.gnu.org/philosophy/no-word-attachments.html
------------------------------------------------------------------
Office location:
 
Bureau 3020 (3rd floor)
Batiment Sophie Germain
Avenue de France
Metro Bibliotheque Francois Mitterrand, ligne 14/RER C
-----------------------------------------------------------------
GPG fingerprint 2931 20CE 3A5A 5390 98EC 8BFC FCCA C3BE 39CB 12D3                        

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-27 12:56                 ` Yaron Minsky
@ 2013-10-27 14:28                   ` Gabriel Scherer
  2013-10-27 14:43                     ` Yaron Minsky
  0 siblings, 1 reply; 27+ messages in thread
From: Gabriel Scherer @ 2013-10-27 14:28 UTC (permalink / raw)
  To: Yaron Minsky; +Cc: Andreas Rossberg, OCaML List Mailing

[-- Attachment #1: Type: text/plain, Size: 3026 bytes --]

> > Note how OCaml already uses '_a for a sort of flexible variable in its
output.
> Where?

'_a is used for type variables that cannot be generalized.

# let x = ref None;;
val x : '_a option ref = {contents = None}
# let id x = x in id id;;
- : '_a -> '_a = <fun>



On Sun, Oct 27, 2013 at 1:56 PM, Yaron Minsky <yminsky@janestreet.com>wrote:

> On Sun, Oct 27, 2013 at 8:16 AM, Andreas Rossberg <rossberg@mpi-sws.org>
> wrote:
> > On Oct 25, 2013, at 22:32 , Yaron Minsky <yminsky@janestreet.com> wrote:
> >> Changing the semantics of this will, I think, break a _lot_ of code.
> >
> > Interesting. Do you have specific examples in mind?
>
> I know that I've seen many examples come up in my code.  One common
> use is to partially specify a type.  For example, if I wanted to
> ignore a return value that is a Tcp.Server.t from Async, I would
> probably write it like this:
>
>     (ignore server : ('a,'b) Tcp.Server.t)
>
> without specifying the sometimes rather complicated details of those
> types.  Similarly, if I were to ignore a Map, I might write
>
>     (ignore map : (int,string,'a) Map.t
>
> since it's not helpful here to specify the comparator type, which is
> what goes into the third slot here.
>
> Nowadays, I would probably use an underscore in these cases rather
> than an explicit type variable, but our codebase has plenty of old
> examples of this kind of thing.  If a change like the one you propose
> is changed, I presume that _ would keep its current meeting, which
> would address many use cases.
>
> Given the existence of such use-cases, I would hope that we could
> avoid making the change in a way that would non-optionally break lots
> of code.  If people agree this change should be made, perhaps it
> should be done in the mode of -strict-sequence.  That change was added
> as a flag, so users could take it at their own pace.
>
> >> For what it's worth, I suspect that most people who are surprised by
> >> this are people who were trained on Standard ML.  At Jane Street we've
> >> had a lot of people learn the language, and the complaints I've heard
> >> about this feature are, I think, mostly from that group.
> >
> > Maybe, but it's not my impression that this is true for most people I
> see asking related questions here on the list or on SO.
>
> To be clear, my guess above is less than scientific.
>
> >> I also don't find Andreas suggestion particularly intuitive.  I would
> >> have guessed that (x: '_a) would constrain x to be a weakly
> >> polymorphic value, which is at odds with the proposal.
> >
> > Now, _that_ is something I would only expect from programmers trained on
> SML -- ancient SML'90 to be precise. ;)
> >
> > Note how OCaml already uses '_a for a sort of flexible variable in its
> output.
>
> Where?
>
> > /Andreas
> >
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>

[-- Attachment #2: Type: text/html, Size: 4176 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-27 14:28                   ` Gabriel Scherer
@ 2013-10-27 14:43                     ` Yaron Minsky
  2013-10-27 15:25                       ` Gabriel Scherer
  0 siblings, 1 reply; 27+ messages in thread
From: Yaron Minsky @ 2013-10-27 14:43 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: Andreas Rossberg, OCaML List Mailing

But isn't this the exact opposite of Andreas' proposal?  He was
proposing using '_a as a unification variable, which may very well be
generalized.  It is exactly this use case for '_a that seems at odds
with Andreas' proposal.

y

On Sun, Oct 27, 2013 at 10:28 AM, Gabriel Scherer
<gabriel.scherer@gmail.com> wrote:
>> > Note how OCaml already uses '_a for a sort of flexible variable in its
>> > output.
>> Where?
>
> '_a is used for type variables that cannot be generalized.
>
> # let x = ref None;;
> val x : '_a option ref = {contents = None}
> # let id x = x in id id;;
> - : '_a -> '_a = <fun>
>
>
>
> On Sun, Oct 27, 2013 at 1:56 PM, Yaron Minsky <yminsky@janestreet.com>
> wrote:
>>
>> On Sun, Oct 27, 2013 at 8:16 AM, Andreas Rossberg <rossberg@mpi-sws.org>
>> wrote:
>> > On Oct 25, 2013, at 22:32 , Yaron Minsky <yminsky@janestreet.com> wrote:
>> >> Changing the semantics of this will, I think, break a _lot_ of code.
>> >
>> > Interesting. Do you have specific examples in mind?
>>
>> I know that I've seen many examples come up in my code.  One common
>> use is to partially specify a type.  For example, if I wanted to
>> ignore a return value that is a Tcp.Server.t from Async, I would
>> probably write it like this:
>>
>>     (ignore server : ('a,'b) Tcp.Server.t)
>>
>> without specifying the sometimes rather complicated details of those
>> types.  Similarly, if I were to ignore a Map, I might write
>>
>>     (ignore map : (int,string,'a) Map.t
>>
>> since it's not helpful here to specify the comparator type, which is
>> what goes into the third slot here.
>>
>> Nowadays, I would probably use an underscore in these cases rather
>> than an explicit type variable, but our codebase has plenty of old
>> examples of this kind of thing.  If a change like the one you propose
>> is changed, I presume that _ would keep its current meeting, which
>> would address many use cases.
>>
>> Given the existence of such use-cases, I would hope that we could
>> avoid making the change in a way that would non-optionally break lots
>> of code.  If people agree this change should be made, perhaps it
>> should be done in the mode of -strict-sequence.  That change was added
>> as a flag, so users could take it at their own pace.
>>
>> >> For what it's worth, I suspect that most people who are surprised by
>> >> this are people who were trained on Standard ML.  At Jane Street we've
>> >> had a lot of people learn the language, and the complaints I've heard
>> >> about this feature are, I think, mostly from that group.
>> >
>> > Maybe, but it's not my impression that this is true for most people I
>> > see asking related questions here on the list or on SO.
>>
>> To be clear, my guess above is less than scientific.
>>
>> >> I also don't find Andreas suggestion particularly intuitive.  I would
>> >> have guessed that (x: '_a) would constrain x to be a weakly
>> >> polymorphic value, which is at odds with the proposal.
>> >
>> > Now, _that_ is something I would only expect from programmers trained on
>> > SML -- ancient SML'90 to be precise. ;)
>> >
>> > Note how OCaml already uses '_a for a sort of flexible variable in its
>> > output.
>>
>> Where?
>>
>> > /Andreas
>> >
>>
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa.inria.fr/sympa/arc/caml-list
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-27 14:43                     ` Yaron Minsky
@ 2013-10-27 15:25                       ` Gabriel Scherer
  2013-10-27 15:41                         ` Yaron Minsky
  0 siblings, 1 reply; 27+ messages in thread
From: Gabriel Scherer @ 2013-10-27 15:25 UTC (permalink / raw)
  To: Yaron Minsky; +Cc: Andreas Rossberg, OCaML List Mailing

[-- Attachment #1: Type: text/plain, Size: 4762 bytes --]

Today the only time where you see '_a is for variable that did not get
generalized, and as a output of the type inference, never as input. But it
would be consistent to extend their meaning to flexible variables anywhere,
regardless of whether they'll get generalized later.

Andreas' idea is to have '_a meaning "instantiate me with any suitable type
that makes this expression type-check" (including a freshly generalized
variable), and have 'a meaning instead "this type must remain a polymorphic
variable". The interpretation for '_a corresponds to the meaning it has
when printed by the type-checker today -- and the interpretation of 'a
would behave as the (type a) construct does today, minus possibly the
specific GADT interaction.

(One minor difference being that, today, the type-checker is not too
careful about respecting weak variable identity when printing them. The
weak variables appearing in the two phrases I've shown have the same name
'_a, when they in fact denote distinct flexible variables which occur in
the same scope.)




On Sun, Oct 27, 2013 at 3:43 PM, Yaron Minsky <yminsky@janestreet.com>wrote:

> But isn't this the exact opposite of Andreas' proposal?  He was
> proposing using '_a as a unification variable, which may very well be
> generalized.  It is exactly this use case for '_a that seems at odds
> with Andreas' proposal.
>
> y
>
> On Sun, Oct 27, 2013 at 10:28 AM, Gabriel Scherer
> <gabriel.scherer@gmail.com> wrote:
> >> > Note how OCaml already uses '_a for a sort of flexible variable in its
> >> > output.
> >> Where?
> >
> > '_a is used for type variables that cannot be generalized.
> >
> > # let x = ref None;;
> > val x : '_a option ref = {contents = None}
> > # let id x = x in id id;;
> > - : '_a -> '_a = <fun>
> >
> >
> >
> > On Sun, Oct 27, 2013 at 1:56 PM, Yaron Minsky <yminsky@janestreet.com>
> > wrote:
> >>
> >> On Sun, Oct 27, 2013 at 8:16 AM, Andreas Rossberg <rossberg@mpi-sws.org
> >
> >> wrote:
> >> > On Oct 25, 2013, at 22:32 , Yaron Minsky <yminsky@janestreet.com>
> wrote:
> >> >> Changing the semantics of this will, I think, break a _lot_ of code.
> >> >
> >> > Interesting. Do you have specific examples in mind?
> >>
> >> I know that I've seen many examples come up in my code.  One common
> >> use is to partially specify a type.  For example, if I wanted to
> >> ignore a return value that is a Tcp.Server.t from Async, I would
> >> probably write it like this:
> >>
> >>     (ignore server : ('a,'b) Tcp.Server.t)
> >>
> >> without specifying the sometimes rather complicated details of those
> >> types.  Similarly, if I were to ignore a Map, I might write
> >>
> >>     (ignore map : (int,string,'a) Map.t
> >>
> >> since it's not helpful here to specify the comparator type, which is
> >> what goes into the third slot here.
> >>
> >> Nowadays, I would probably use an underscore in these cases rather
> >> than an explicit type variable, but our codebase has plenty of old
> >> examples of this kind of thing.  If a change like the one you propose
> >> is changed, I presume that _ would keep its current meeting, which
> >> would address many use cases.
> >>
> >> Given the existence of such use-cases, I would hope that we could
> >> avoid making the change in a way that would non-optionally break lots
> >> of code.  If people agree this change should be made, perhaps it
> >> should be done in the mode of -strict-sequence.  That change was added
> >> as a flag, so users could take it at their own pace.
> >>
> >> >> For what it's worth, I suspect that most people who are surprised by
> >> >> this are people who were trained on Standard ML.  At Jane Street
> we've
> >> >> had a lot of people learn the language, and the complaints I've heard
> >> >> about this feature are, I think, mostly from that group.
> >> >
> >> > Maybe, but it's not my impression that this is true for most people I
> >> > see asking related questions here on the list or on SO.
> >>
> >> To be clear, my guess above is less than scientific.
> >>
> >> >> I also don't find Andreas suggestion particularly intuitive.  I would
> >> >> have guessed that (x: '_a) would constrain x to be a weakly
> >> >> polymorphic value, which is at odds with the proposal.
> >> >
> >> > Now, _that_ is something I would only expect from programmers trained
> on
> >> > SML -- ancient SML'90 to be precise. ;)
> >> >
> >> > Note how OCaml already uses '_a for a sort of flexible variable in its
> >> > output.
> >>
> >> Where?
> >>
> >> > /Andreas
> >> >
> >>
> >> --
> >> Caml-list mailing list.  Subscription management and archives:
> >> https://sympa.inria.fr/sympa/arc/caml-list
> >> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> >> Bug reports: http://caml.inria.fr/bin/caml-bugs
> >
> >
>

[-- Attachment #2: Type: text/html, Size: 6691 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-27 15:25                       ` Gabriel Scherer
@ 2013-10-27 15:41                         ` Yaron Minsky
  0 siblings, 0 replies; 27+ messages in thread
From: Yaron Minsky @ 2013-10-27 15:41 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: Andreas Rossberg, OCaML List Mailing

I trust you that it's a consistent interpretation, but it still
strikes me as surprising, and I suspect it would be so for new users.
From a user's perspective, you only see '_a now when there a weakly
polymorphic type variable is inferred.  Andreas' proposal is that as
an annotation, this should imply a unification variable, i.e., a
constraint on what can be inferred for that type.  I don't know why
those both count as "flexible variables" (not surprising, since I had
not heard of them before this conversation), but I'm not sure it
matters much.

The new situation seems not a lot clearer than the old, merely moving
around the confusion from one syntax to another.  All told, following
Roberto's observation, I suspect there isn't enough of a win here to
justify changing the meaning of old syntax.

y

On Sun, Oct 27, 2013 at 11:25 AM, Gabriel Scherer
<gabriel.scherer@gmail.com> wrote:
> Today the only time where you see '_a is for variable that did not get
> generalized, and as a output of the type inference, never as input. But it
> would be consistent to extend their meaning to flexible variables anywhere,
> regardless of whether they'll get generalized later.
>
> Andreas' idea is to have '_a meaning "instantiate me with any suitable type
> that makes this expression type-check" (including a freshly generalized
> variable), and have 'a meaning instead "this type must remain a polymorphic
> variable". The interpretation for '_a corresponds to the meaning it has when
> printed by the type-checker today -- and the interpretation of 'a would
> behave as the (type a) construct does today, minus possibly the specific
> GADT interaction.
>
> (One minor difference being that, today, the type-checker is not too careful
> about respecting weak variable identity when printing them. The weak
> variables appearing in the two phrases I've shown have the same name '_a,
> when they in fact denote distinct flexible variables which occur in the same
> scope.)
>
>
>
>
> On Sun, Oct 27, 2013 at 3:43 PM, Yaron Minsky <yminsky@janestreet.com>
> wrote:
>>
>> But isn't this the exact opposite of Andreas' proposal?  He was
>> proposing using '_a as a unification variable, which may very well be
>> generalized.  It is exactly this use case for '_a that seems at odds
>> with Andreas' proposal.
>>
>> y
>>
>> On Sun, Oct 27, 2013 at 10:28 AM, Gabriel Scherer
>> <gabriel.scherer@gmail.com> wrote:
>> >> > Note how OCaml already uses '_a for a sort of flexible variable in
>> >> > its
>> >> > output.
>> >> Where?
>> >
>> > '_a is used for type variables that cannot be generalized.
>> >
>> > # let x = ref None;;
>> > val x : '_a option ref = {contents = None}
>> > # let id x = x in id id;;
>> > - : '_a -> '_a = <fun>
>> >
>> >
>> >
>> > On Sun, Oct 27, 2013 at 1:56 PM, Yaron Minsky <yminsky@janestreet.com>
>> > wrote:
>> >>
>> >> On Sun, Oct 27, 2013 at 8:16 AM, Andreas Rossberg
>> >> <rossberg@mpi-sws.org>
>> >> wrote:
>> >> > On Oct 25, 2013, at 22:32 , Yaron Minsky <yminsky@janestreet.com>
>> >> > wrote:
>> >> >> Changing the semantics of this will, I think, break a _lot_ of code.
>> >> >
>> >> > Interesting. Do you have specific examples in mind?
>> >>
>> >> I know that I've seen many examples come up in my code.  One common
>> >> use is to partially specify a type.  For example, if I wanted to
>> >> ignore a return value that is a Tcp.Server.t from Async, I would
>> >> probably write it like this:
>> >>
>> >>     (ignore server : ('a,'b) Tcp.Server.t)
>> >>
>> >> without specifying the sometimes rather complicated details of those
>> >> types.  Similarly, if I were to ignore a Map, I might write
>> >>
>> >>     (ignore map : (int,string,'a) Map.t
>> >>
>> >> since it's not helpful here to specify the comparator type, which is
>> >> what goes into the third slot here.
>> >>
>> >> Nowadays, I would probably use an underscore in these cases rather
>> >> than an explicit type variable, but our codebase has plenty of old
>> >> examples of this kind of thing.  If a change like the one you propose
>> >> is changed, I presume that _ would keep its current meeting, which
>> >> would address many use cases.
>> >>
>> >> Given the existence of such use-cases, I would hope that we could
>> >> avoid making the change in a way that would non-optionally break lots
>> >> of code.  If people agree this change should be made, perhaps it
>> >> should be done in the mode of -strict-sequence.  That change was added
>> >> as a flag, so users could take it at their own pace.
>> >>
>> >> >> For what it's worth, I suspect that most people who are surprised by
>> >> >> this are people who were trained on Standard ML.  At Jane Street
>> >> >> we've
>> >> >> had a lot of people learn the language, and the complaints I've
>> >> >> heard
>> >> >> about this feature are, I think, mostly from that group.
>> >> >
>> >> > Maybe, but it's not my impression that this is true for most people I
>> >> > see asking related questions here on the list or on SO.
>> >>
>> >> To be clear, my guess above is less than scientific.
>> >>
>> >> >> I also don't find Andreas suggestion particularly intuitive.  I
>> >> >> would
>> >> >> have guessed that (x: '_a) would constrain x to be a weakly
>> >> >> polymorphic value, which is at odds with the proposal.
>> >> >
>> >> > Now, _that_ is something I would only expect from programmers trained
>> >> > on
>> >> > SML -- ancient SML'90 to be precise. ;)
>> >> >
>> >> > Note how OCaml already uses '_a for a sort of flexible variable in
>> >> > its
>> >> > output.
>> >>
>> >> Where?
>> >>
>> >> > /Andreas
>> >> >
>> >>
>> >> --
>> >> Caml-list mailing list.  Subscription management and archives:
>> >> https://sympa.inria.fr/sympa/arc/caml-list
>> >> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> >> Bug reports: http://caml.inria.fr/bin/caml-bugs
>> >
>> >
>
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Caml-list] Equality between abstract type definitions
  2013-10-25  6:44   ` Andreas Rossberg
  2013-10-25  8:29     ` Roberto Di Cosmo
@ 2013-10-28  3:30     ` Jacques Garrigue
  1 sibling, 0 replies; 27+ messages in thread
From: Jacques Garrigue @ 2013-10-28  3:30 UTC (permalink / raw)
  To: Andreas Rossberg; +Cc: OCaml Mailing List

Dear Andreas,

It is a bit late to enter this discussion, but I just have two comments

1) All the bug reports (and messages on this list, but for this one) I have seen were
  about the non-generalization of type variables, not their interpretation. Namely,
  people have a hard time understanding why the following is not accepted:

    let f () =
      let id : 'a -> 'a = fun x -> x in
      (id 1, id true)

  I agree that in this respect SML’s choice of inferring a minimal scope (and allowing
  local generalization of named type variables) is more helpful.
  This part could be implemented without breaking existing programs.
  Note however that we already have other ways of introducing local type variables.
  (For instance, writing " id : ‘a. ‘a -> ‘a " in the above.)

2) In ocaml, type variables are also used for describing sharing in recursive types:
     (<m : int; self : 'a> as ‘a)
    and also for talking about types that have a row variable
     (< m : int; .. > as ‘a) -> ‘a
    These two cases use an existential view of type variables.

Jacques

> On Oct 25, 2013, at 01:23 , Jacques Garrigue <garrigue@math.nagoya-u.ac.jp> wrote:
>> In OCaml, type variables used in type annotations are just unification variables:
>> the type checker is allowed to merge them or instantiate them.
>> This is useful when you want to indicate that two things have the same type,
>> without writing the type by hand.
> 
> Jacques, do you think there is any chance that this will ever be changed? I think this keeps being one of the most annoying pitfalls in the OCaml type system, not what most people expect, and in 98% of the cases, not what they want either -- especially since there often is no convenient way to actually express what they want.
> 
> A simple proposal, which I'm sure has been made many times before, would be to interpret type variables of the form 'a, 'b as proper universal variables, and only ones of the form '_a, '_b as unification variables. That matches the notation that OCaml has always been using in its output. More expressive and clearer signalling of intent.
> 
> Obviously, such a change would break some code, code that actually relies on 'a being just a unification variable. But my optimistic guess is that such code is rather rare. And it would be trivial to adapt.
> 
> It would also break code that assumed the wrong behaviour and only compiled by accident (such as the Peter's example). But arguably, that's a good thing, because it uncovers actual bugs.
> 
> Anyway, just dreaming aloud… :)
> 
> /Andreas
> 


^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2013-10-28  3:30 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-24 22:57 [Caml-list] Equality between abstract type definitions Peter Frey
2013-10-24 23:23 ` Jacques Garrigue
2013-10-25  6:44   ` Andreas Rossberg
2013-10-25  8:29     ` Roberto Di Cosmo
2013-10-25  9:59       ` Ivan Gotovchits
2013-10-25 11:09         ` Gabriel Scherer
2013-10-25 14:24           ` Andreas Rossberg
2013-10-25 20:32             ` Yaron Minsky
2013-10-25 20:44               ` Jacques Le Normand
2013-10-26  1:08                 ` Norman Hardy
2013-10-26  5:28                   ` Jacques Garrigue
2013-10-27 12:16               ` Andreas Rossberg
2013-10-27 12:56                 ` Yaron Minsky
2013-10-27 14:28                   ` Gabriel Scherer
2013-10-27 14:43                     ` Yaron Minsky
2013-10-27 15:25                       ` Gabriel Scherer
2013-10-27 15:41                         ` Yaron Minsky
2013-10-25 12:35         ` Roberto Di Cosmo
2013-10-25 12:45           ` Jonathan Protzenko
2013-10-25 13:20             ` Roberto Di Cosmo
2013-10-25 14:03       ` Andreas Rossberg
2013-10-26  9:07         ` oleg
2013-10-26 14:11           ` Didier Remy
2013-10-26 17:32         ` Didier Remy
2013-10-27 12:07           ` Andreas Rossberg
2013-10-27 14:10             ` Roberto Di Cosmo
2013-10-28  3:30     ` Jacques Garrigue

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).