[Caml-list] Improving OCaml's choice of type to display

9 views
Skip to first unread message

Yaron Minsky

unread,
Oct 8, 2009, 9:40:38 PM10/8/09
to caml...@yquem.inria.fr
Anyone who plays around with the Core library that Jane Street just released
can see showcased a rather ugly detail of how Core's design interacts with
how OCaml displays types. Witness:

# Int.of_string;;
- : string -> Core.Std.Int.stringable = <fun>
# Float.of_string;;
- : string -> Core_extended.Std.Float.stringable = <fun>

I'd be much happier if this was rendered in the following equally correct
and more readable form:

# Int.of_string;;
- : string -> Int.t = <fun>
# Float.of_string;;
- : string -> Float.t = <fun>

Or even:

# Int.of_string;;
- : string -> int = <fun>
# Float.of_string;;
- : string -> float = <fun>

And this isn't just an issue in the top-level. The compiler also displays
types in the same difficult to read form. I'm wondering if anyone has some
thoughts as to what we can do to make the compiler make better choices
here. There are two issues to overcome:

- Dropping the module name. I'd love to give the compiler the hint that
Core.Std. could be dropped from the prefix in a context where that module is
open. This is what's done with the pervasives module already, I believe, so
it seems like it should be doable here.
- Choosing shorter names. This one seems harder, but there are various
different possibilities for what type name to print out, and a reasonable
heuristic to use might be to pick the shortest one. Part of the reason
these issues come up is our use of standardized interface components (that's
where the "stringable" type name comes from). I suspect this one will be
hard to fix, sadly.

Anyway, we'd be happy with any suggestions on how to improve matters.

y

Yaron Minsky

unread,
Oct 8, 2009, 9:53:54 PM10/8/09
to caml...@yquem.inria.fr
And you can compete to come up with the most innocuous code that comes up
with the longest type. Here's my current favorite:

# open Option.Monad_infix;;
# Map.find m 3 >>| fun x -> x + 1;;
- : int Core.Std.Option.Monad_infix.monad = Some 4

Which of course could be rendered as:

# open Option.Monad_infix;;
# Map.find m 3 >>| fun x -> x + 1;;
- : int option = Some 4

y

Andrej Bauer

unread,
Oct 9, 2009, 3:33:13 AM10/9/09
to ymi...@gmail.com, caml...@yquem.inria.fr
On Fri, Oct 9, 2009 at 3:40 AM, Yaron Minsky <ymi...@gmail.com> wrote:
> Choosing shorter names.

By which you probably mean "the fewest number of dots (module
projections)". It might be a bit annoying if the code that prints
doesn't know what modules are open. What do the INRIA priests say?

Andrej

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

Yaron Minsky

unread,
Oct 9, 2009, 5:58:16 AM10/9/09
to Andrej Bauer, caml...@yquem.inria.fr
Well, if we're picking heuristics, the fewest number of characters wouldn't
be crazy either. Given the choice between Int.t and Int.comparable (which
are aliases for the same type), I'd prefer to see Int.t.

y

Alp Mestan

unread,
Oct 9, 2009, 6:54:47 AM10/9/09
to ymi...@gmail.com, caml...@yquem.inria.fr, Andrej Bauer
Can't there be a trick by playing with, e.g, ocamlmktop, which could open
Core and its main submodules by default, like it's done with Pervasives and,
IIRC, Batteries ?

> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>


--
Alp Mestan
http://alpmestan.wordpress.com/
http://alp.developpez.com/

Yaron Minsky

unread,
Oct 9, 2009, 7:15:19 AM10/9/09
to Alp Mestan, caml...@yquem.inria.fr, Andrej Bauer
On Fri, Oct 9, 2009 at 6:54 AM, Alp Mestan <a...@mestan.fr> wrote:

> Can't there be a trick by playing with, e.g, ocamlmktop, which could open
> Core and its main submodules by default, like it's done with Pervasives and,
> IIRC, Batteries ?
>

Maybe. Although to be honest my main concern is not with the top-level, but
rather with the errors given out by ocamlc, and the type-inference hints
given by the -dtypes flag. The naming choices are easiest to see in the
toplevel, but they show up all over the place.

Damien Guichard

unread,
Oct 9, 2009, 10:18:58 AM10/9/09
to caml...@yquem.inria.fr

Hi Yaron,

I think you better think twice about the problem in general (rather than the particular needs of Core) before proposing some controversial type display improvement.

Imagine my code is:

type color = int

let black : color = 0

Then, following your proposition, evaluating black should give me an int rather than a color because int is shorter and therefore nicer.

So, now, what's the point in the color type declaration ?
There is none, type aliasing becomes useless because you can't expose it.
Call me crazy but i whish i can use more than 3 characters as a type name.

So you want it to be displayed as an Int.t rather than an Int.comparable ?
Then just declare it as Int.t rather than Int.comparable, or choose another shorter name, it's not an OCaml issue, its' a Core issue.
(obviously it would really help if no english word would be more than 6 characters but Ocaml can't be blamed for that)

I mean, when designing an elaborate software library, you have to make choices, and often, no matter how good OCaml is, some choices will be compromises. You have to pick the lesser between several evils and live with it.

I have learned that when programming Ocaml-Idaho, suddenly module names become longer, module types become more composited, data types become more subtle, and so on and so on...

Blaming OCaml is a too easy path.

At one certain point you have to face the verbosity you have created and decide whether the additionnal expressivity worths the price.
If you think it does then it's ok, if not then just amend, if amending doesn't help then consider refactoring.
Seek the best expressiveness/verbosity ratio without sacrifying too much functionality.
That's your job as a library designer.


- damien

En r�ponse au message
de : Yaron Minsky
du : 2009-10-09 11:58:11
� : Andrej Bauer
CC : caml...@yquem.inria.fr
Sujet : Re: [Caml-list] Improving OCaml's choice of type to display

Vincent Aravantinos

unread,
Oct 9, 2009, 10:45:18 AM10/9/09
to Damien Guichard, caml...@yquem.inria.fr
Hi,

can't you just say that you spotted a problem in the proposed solution
instead of being so aggressive?

Removing all the useless sentences of your message just leave this:

Le 9 oct. 09 � 16:18, Damien Guichard a �crit :

> Imagine my code is:
>
> type color = int
>
> let black : color = 0
>
> Then, following your proposition, evaluating black should give me an
> int rather than a color because int is shorter and therefore nicer.


which is indeed relevant and exposes a problem not faced in the
previous mails.

Thanks,
V.

David Allsopp

unread,
Oct 9, 2009, 11:28:19 AM10/9/09
to Vincent Aravantinos, Damien Guichard, caml...@yquem.inria.fr
> Le 9 oct. 09 � 16:18, Damien Guichard a �crit :
>
>
> Imagine my code is:
>�
>� type color = int
>�
>� let black : color = 0�
>�
> Then, following your proposition, evaluating�black�should give me
an�int�rather than a�color�because�int�is shorter and therefore nicer.

Hmm, I'd say that having OCaml respond "val black : int = 0" is indeed the
more useful answer (but not because int is shorter)... there are quite often
times where you get complex looking types (for good reason) which are in
fact aliases of much simpler types where it would (IMO) be much nicer for
OCaml to "call a spade a spade" and just tell you it's an int (Set.Make and
Map.Make being obvious cases[1]). Perhaps OCaml could make us both happy by
responding "val black : color = int = 0" (i.e. show the inferred and
possibly aliased type and also the principal base type, if it's different
from the inferred type)

The "unnecessary" complexity of the type names can also arise quite easily
if you're using with functors so need to present a particular type to
satisfy a signature - at which point having Foo.Bar.Other.Module.t (which is
in fact an int) may create irritatingly long type messages but the structure
being that way is probably hugely useful when it gets applied to
Magic.Make(Foo) elsewhere...


David


[1] Consider, somewhat obtusely, [let x : Map.Make(String).key = ""] (which
in real code is inferred rather more trivially from anything manipulating
sets and maps)

Yaron Minsky

unread,
Oct 9, 2009, 12:52:54 PM10/9/09
to Damien Guichard, caml...@yquem.inria.fr
I do basically think of this as a deficiency in the compiler as opposed to a
deficiency in core (although it's hardly a major deficiency in the
compiler). Signatures, modules and functors are an important part of the
language, and if you want to use them in a significant way, then you will
end up having multiple paths to get to the same type. OCaml's algorithm for
choosing the type to display is somewhat unfortunate in this regard.

If you have a design approach that simultaneously makes good use of
functors, modules and signatures and makes OCaml's type-to-display-selector
happy, I'd be very interested in hearing it.

Finally, the specific point you make argues against the specific heuristic
(smallest type name) I proposed, but not against all other heuristics.
Another heuristic which I think has some potential is choosing the type name
with the smallest number of dots. (also, as a matter of personal
preference, in the case that you outline, I would prefer the answer of "int"
to "color", but that is just a coincidence, of course.)

To be clear, some of this stuff can be made better by using signature
functors, but that has its own problems in terms of messiness and
boilerplate. That said, I have half a mind to write a syntax extension to
clean that up, and switch over to signature functors, for this and other
reasons. That said, signature functors only clean up a little bit of the
problem.

y

On Fri, Oct 9, 2009 at 10:18 AM, Damien Guichard <alpha...@orange.fr>wrote:

>
> Hi Yaron,
>
> I think you better think twice about the problem in general (rather than
> the particular needs of Core) before proposing some controversial type
> display improvement.
>
> Imagine my code is:
>
> type color = int
>
> let black : color = 0
>

> Then, following your proposition, evaluating *black* should give me an *
> int* rather than a *color* because *int* is shorter and therefore nicer.
>
> So, now, what's the point in the *color* type declaration ?


> There is none, type aliasing becomes useless because you can't expose it.
> Call me crazy but i whish i can use more than 3 characters as a type name.
>

> So you want it to be displayed as an *Int.t* rather than an *
> Int.comparable* ?
> Then just declare it as *Int.t* rather than *Int.comparable*, or choose


> another shorter name, it's not an OCaml issue, its' a Core issue.
> (obviously it would really help if no english word would be more than 6
> characters but Ocaml can't be blamed for that)
>
> I mean, when designing an elaborate software library, you have to make
> choices, and often, no matter how good OCaml is, some choices will be
> compromises. You have to pick the lesser between several evils and live with
> it.
>

> I have learned that when programming Ocaml-Idaho<https://forge.ocamlcore.org/projects/ocaml-idaho/>,


> suddenly module names become longer, module types become more composited,
> data types become more subtle, and so on and so on...
>
> Blaming OCaml is a too easy path.
>

> At one certain point you have to face the verbosity *you* have created and


> decide whether the additionnal expressivity worths the price.
> If you think it does then it's ok, if not then just amend, if amending
> doesn't help then consider refactoring.
> Seek the best expressiveness/verbosity ratio without sacrifying too much
> functionality.
> That's your job as a library designer.
>
>

> - *damien*
>
>
> ------------------------------
> *En r�ponse au message*
> *de :* Yaron Minsky
> *du :* 2009-10-09 11:58:11
> *� :* Andrej Bauer
> *CC :* caml...@yquem.inria.fr
> *Sujet :* Re: [Caml-list] Improving OCaml's choice of type to display


>
> Well, if we're picking heuristics, the fewest number of characters wouldn't
> be crazy either. Given the choice between Int.t and Int.comparable (which
> are aliases for the same type), I'd prefer to see Int.t.
>
> y
>
> On Fri, Oct 9, 2009 at 3:33 AM, Andrej Bauer <andrej...@andrej.com>wrote:
>
>> On Fri, Oct 9, 2009 at 3:40 AM, Yaron Minsky <ymi...@gmail.com> wrote:
>> > Choosing shorter names.
>>
>> By which you probably mean "the fewest number of dots (module
>> projections)". It might be a bit annoying if the code that prints
>> doesn't know what modules are open. What do the INRIA priests say?
>>
>> Andrej
>>
>
>

Stephen Weeks

unread,
Oct 9, 2009, 2:14:22 PM10/9/09
to caml...@yquem.inria.fr
On Fri, Oct 9, 2009 at 3:33 AM, Andrej Bauer <andrej...@andrej.com> wrote:
> On Fri, Oct 9, 2009 at 3:40 AM, Yaron Minsky <ymi...@gmail.com> wrote:
>> Choosing shorter names.
>
> By which you probably mean "the fewest number of dots (module
> projections)".

That is the rule we used in MLton, breaking ties by
most-recently-defined. It worked quite well in practice.

See
http://mlton.org/TypeChecking

Damien Guichard

unread,
Oct 9, 2009, 2:23:28 PM10/9/09
to caml...@yquem.inria.fr

> If you have a design approach that simultaneously makes good use of functors,
> modules and signatures and makes OCaml's type-to-display-selector happy, I'd be very interested in hearing it.

Indeed, good use of functors, modules and signatures doesn't come without type verbosity.
I have also faced it, it's a real concern.
The Core user or library user has to be tolerant, not every type can be called t, not every module can be called M, modules have to include further modules, as a result type paths become longer.
Plus functors add module as parameters and as a result types become more difficult to interpret.
Main part of the answer lies in accepting the cultural shock.
More capable code libraries come with a steepier learning curve, both as a user and as an implementer.

> To be clear, some of this stuff can be made better by using signature functors, but that has its own problems in terms of messiness and
> boilerplate.

Ocaml-Idaho signatures are done by composing more elementary module types.
As a result the design is highly modular but you end up with more boilerplate and type equalities.
However type equalities have a good reason, they capture the context.
The context is more important than what the actual type is.

May be the toplevel could be more aware of opened modules then your example would be rendered as :

# open Option.Monad_infix;;
# Map.find m 3 >>| fun x -> x + 1;;

- : int monad = Some 4

That would be much shorter without erasing type equalities.

- damien


PS:

As a module design example here is an excerpt of the OCaml-Idaho UnbalancedMap module, which has both a Mutable and a Pure version implemented as recursive modules. On one hand it's pure boilerplate, on the other hand it's just plain usage of ML modules.


module rec Mutable
:
functor (Ord: Interfaces.Ordered) ->
sig
include Interfaces.MutableMap
with type key = Ord.ordered
include Interfaces.MutableKeySet
with type 'a set = 'a map and type set_key = key
include Interfaces.OrderedKeyFoldable
with type 'a foldable = 'a map and type fold_key = key
val inserted: key -> 'a -> 'a map -> bool
val root_inserted: key -> 'a -> 'a map -> bool
val flatten_map: (key -> 'a -> 'a map) -> 'a map -> 'a map
val to_pure: 'a map -> 'a Pure(Ord).map
val to_pure_unsafe: 'a map -> 'a Pure(Ord).map
end
=
functor (Ord: Interfaces.Ordered) ->
struct

include BinaryTree_Keyed.Make(Ord)

module Order = Ord

type 'a map = 'a tree ref
type 'a foldable = 'a map and fold_key = key
type ('a,'b) fold = (key -> 'a -> 'b -> 'b) -> 'b -> 'a map -> 'b

type 'a set = 'a map
type set_key = key
type 'a set_select = 'a select

...

end

and Pure
:
functor (Ord: Interfaces.Ordered) ->
sig
include Interfaces.PureMap
with type key = Ord.ordered
include Interfaces.PureKeySet
with type 'a set = 'a map and type set_key = key
include Interfaces.OrderedKeyFoldable
with type 'a foldable = 'a map and type fold_key = key
val root_add: key -> 'a -> 'a map -> 'a map
val splay_add: key -> 'a -> 'a map -> 'a map
val splay_lookup: key -> 'a map -> 'a map * 'a option
val splay_find: key -> 'a map -> 'a map * 'a
val flatten_map: (key -> 'a -> 'a map) -> 'a map -> 'a map
val to_mutable: 'a map -> 'a Mutable(Ord).map
val to_mutable_unsafe: 'a map -> 'a Mutable(Ord).map
end
=
functor (Ord: Interfaces.Ordered) ->
struct

include BinaryTree_Keyed.Make(Ord)

module Order = Ord

type 'a map = 'a tree
type 'a foldable = 'a map and fold_key = key
type ('a,'b) fold = (key -> 'a -> 'b -> 'b) -> 'b -> 'a map -> 'b

type 'a set = 'a map
type set_key = key
type 'a set_select = 'a select

...

end

En r�ponse au message
de : Yaron Minsky

du : 2009-10-09 18:52:40
� : Damien Guichard
CC : caml...@yquem.inria.fr
Sujet : Re: [Caml-list] Improving OCaml's choice of type to display

I do basically think of this as a deficiency in the compiler as opposed to a deficiency in core (although it's hardly a major deficiency in the compiler). Signatures, modules and functors are an important part of the language, and if you want to use them in a significant way, then you will end up having multiple paths to get to the same type. OCaml's algorithm for choosing the type to display is somewhat unfortunate in this regard.

If you have a design approach that simultaneously makes good use of functors, modules and signatures and makes OCaml's type-to-display-selector happy, I'd be very interested in hearing it.

Finally, the specific point you make argues against the specific heuristic (smallest type name) I proposed, but not against all other heuristics. Another heuristic which I think has some potential is choosing the type name with the smallest number of dots. (also, as a matter of personal preference, in the case that you outline, I would prefer the answer of "int" to "color", but that is just a coincidence, of course.)

To be clear, some of this stuff can be made better by using signature functors, but that has its own problems in terms of messiness and boilerplate. That said, I have half a mind to write a syntax extension to clean that up, and switch over to signature functors, for this and other reasons. That said, signature functors only clean up a little bit of the problem.

y

On Fri, Oct 9, 2009 at 10:18 AM, Damien Guichard <alpha...@orange.fr> wrote:


Hi Yaron,

I think you better think twice about the problem in general (rather than the particular needs of Core) before proposing some controversial type display improvement.

Imagine my code is:

type color = int

let black : color = 0

Then, following your proposition, evaluating black should give me an int rather than a color because int is shorter and therefore nicer.

So, now, what's the point in the color type declaration ?


There is none, type aliasing becomes useless because you can't expose it.
Call me crazy but i whish i can use more than 3 characters as a type name.

So you want it to be displayed as an Int.t rather than an Int.comparable ?
Then just declare it as Int.t rather than Int.comparable, or choose another shorter name, it's not an OCaml issue, its' a Core issue.


(obviously it would really help if no english word would be more than 6 characters but Ocaml can't be blamed for that)

I mean, when designing an elaborate software library, you have to make choices, and often, no matter how good OCaml is, some choices will be compromises. You have to pick the lesser between several evils and live with it.

I have learned that when programming Ocaml-Idaho, suddenly module names become longer, module types become more composited, data types become more subtle, and so on and so on...

Blaming OCaml is a too easy path.

At one certain point you have to face the verbosity you have created and decide whether the additionnal expressivity worths the price.


If you think it does then it's ok, if not then just amend, if amending doesn't help then consider refactoring.
Seek the best expressiveness/verbosity ratio without sacrifying too much functionality.
That's your job as a library designer.


- damien

En r�ponse au message
de : Yaron Minsky
du : 2009-10-09 11:58:11
� : Andrej Bauer
CC : caml...@yquem.inria.fr

Sujet : Re: [Caml-list] Improving OCaml's choice of type to display

Damien Guichard

unread,
Oct 10, 2009, 11:08:17 AM10/10/09
to caml...@yquem.inria.fr

As Ocaml modules are essentially ML modules, the MLton experience is certainly one to be carefully considered.
People, please don't hesitate to elaborate about how (un-)happy you are with ML/MLton alternate type naming strategies.

- damien

En r�ponse au message

de : Stephen Weeks
du : 2009-10-09 20:14:18
� : caml...@yquem.inria.fr
CC :

Sujet : Re: [Caml-list] Improving OCaml's choice of type to display

Jun Furuse

unread,
Oct 11, 2009, 10:57:30 AM10/11/09
to ymi...@gmail.com, caml...@yquem.inria.fr
I have quickly wrote a small patch against 3.11.1 for this feature, to
see what it would be like.

http://sites.google.com/a/furuse.info/jun/hacks/other-small-ocaml-patches

With this patch, path names are printed without opened modules in the
context. It also tries heuristic data type name simplification: if a
variant/record data type is an alias of another data type whose name
is shorter than the original, the printer uses the latter.

For example:

# open Hashtbl;;
# let tbl = Hashtbl.create 10;;
val tbl : ('_a, '_b) t = <abstr> (* not Hashtbl.t, since Hashtbl is open *)

# type t = int;;
type t = int
# type long_name = int;;
type long_name = int
# (1 : t);;
- : t = 1 (* t is the shorter than its original type int *)
# (1 : long_name);;
- : int = 1 (* int is shorter name for long_name. t
is even shorter but not aliased unfortunatelly. *)

I warn you that the patch is very quickly written and not tested well. Enjoy!

Jun

>> Dropping the module name.� I'd love to give the compiler the hint that
>> Core.Std. could be dropped from the prefix in a context where that module is
>> open.� This is what's done with the pervasives module already, I believe, so
>> it seems like it should be doable here.

>> Choosing shorter names.� This one seems harder, but there are various
>> different possibilities for what type name to print out, and a reasonable
>> heuristic to use might be to pick the shortest one.� Part of the reason
>> these issues come up is our use of standardized interface components (that's
>> where the "stringable" type name comes from).� I suspect this one will be
>> hard to fix, sadly.
>>
>> Anyway, we'd be happy with any suggestions on how to improve matters.
>>
>> y
>
>

Yaron Minsky

unread,
Oct 11, 2009, 11:13:00 AM10/11/09
to Jun Furuse, caml...@yquem.inria.fr
Cool! That was quick.

Does this patch also implement stephen's fewest-number-of-dots
heuristic? I was thinking one nice approach would be fewest-number-of-
dots with ties broken by length of final identifier.

Y

Yaron Minsky

Jun Furuse

unread,
Oct 11, 2009, 11:24:53 AM10/11/09
to Yaron Minsky, caml...@yquem.inria.fr
I have not tested it well but it counts dots and should try to find
the minimal one.

A problem I have found so far is that it prints something confusing, ex.

module M = struct type t end
module N = struct type t end
open M
open N

let _ = ( 1 : M.t )

>> Error: This expression has type int but an expression was expected of type t (which t ?!?!?)

If there are types M.t and N.t and the both of M and N are opened,
these types are printed just "t". This can be avoided by testing the
result name "t" against the current typing envrionment to see it
really means the original type "M.t". This requires more coding but
the weekend has ended in the far east already :-) (It's 0:24 Monday
now.)

Jun

On Mon, Oct 12, 2009 at 12:12 AM, Yaron Minsky <ymi...@gmail.com> wrote:
> Cool! �That was quick.
>
> Does this patch also implement stephen's fewest-number-of-dots heuristic? �I

> was thinking one nice approach would be fewest-number-of-dots with ties

Gilles Pirio

unread,
Oct 11, 2009, 3:57:45 PM10/11/09
to caml...@yquem.inria.fr
On the same topic, I was wondering why the type of the ampl_scalar_app
function below was displayed as ('a -> 'a -> float) -> 'a -> 'a -> float
rather than ('a -> 'a -> float) -> 'a -> ('a -> float). The latter would
make my life easier.

# let ampl_scalar_app f p = if f p p > 1. then fun x->f x p else fun x->f p
x;;
val ampl_scalar_app : ('a -> 'a -> float) -> 'a -> 'a -> float = <fun>

PS: I can imagine this has been discussed extensively before, feel free to
just send my a link to the relevant discussion if that's the case :)

Giles

Damien Guichard

unread,
Oct 11, 2009, 5:17:53 PM10/11/09
to caml...@yquem.inria.fr

Hi Gilles,

The type display routine uses right-associativity of the -> operator as a rewriting rule.
Thus ('a -> 'a -> float) and 'a -> ('a -> float) are the same type and are both displayed as 'a -> 'a -> float.

The type 'a -> ('a -> float) means the application will be (f x) y which is actually the same as f x y because the application is left-associative.
The typer system doesn't care about your actual code syntax, and rightly so because the typer system is about semantic.
You intend to write (f x) y, yet the type system tells you intend to write f x y, that's quite disturbing at first encounter.

Suffice to say you have to get your head around it.
Mind the right-associativity of -> and the left-associativity of application.
Think your code more semantically and less syntactically.
In the end this type sytem makes you a better programmer.

- damien

En r�ponse au message

de : Gilles Pirio
du : 2009-10-11 21:57:40
� : caml...@yquem.inria.fr
CC :
Sujet : Re: [Caml-list] Re: Improving OCaml's choice of type to display

Gilles Pirio

unread,
Oct 11, 2009, 5:46:23 PM10/11/09
to Damien Guichard, caml...@yquem.inria.fr
Hey Damien

Sure, I fully understand that both types are equivalent given the rules
governing the application operator. My point was more on the usability side,
as the type display is primarily intended at helping the programmer to
quickly figure out type mismatch. So I'd think having a display allowing to
quickly distinguish between the noe and castro functions below would be a
good thing, especially for beginners. I've been using ocaml for a few years
now, and I have to say that it's not a major issue any more - just wanted to
give some feedback about this.

Thanks
Gilles


# let noe a b = a;;
val noe : 'a -> 'b -> 'a = <fun>
# let castro a = fun _ -> a;;
val castro : 'a -> 'b -> 'a = <fun>


On Sun, Oct 11, 2009 at 2:17 PM, Damien Guichard <alpha...@orange.fr>wrote:

>
> Hi Gilles,
>
> The type display routine uses right-associativity of the -> operator as a
> rewriting rule.

> Thus *('a -> 'a -> float)* and *'a -> ('a -> float)* are the same type and
> are both displayed as *'a -> 'a -> float*.
>
> The type *'a -> ('a -> float)* means the application will be *(f x) y*which is actually the same as
> *f x y* because the application is left-associative.


> The typer system doesn't care about your actual code syntax, and rightly so
> because the typer system is about semantic.

> You intend to write *(f x) y,* yet the type system tells you intend to
> write *f x y*, that's quite disturbing at first encounter.


>
> Suffice to say you have to get your head around it.
> Mind the right-associativity of -> and the left-associativity of
> application.
> Think your code more semantically and less syntactically.
> In the end this type sytem makes you a better programmer.
>

> - *damien*
>
>
> ------------------------------
> *En r�ponse au message*

> *de :* Gilles Pirio
> *du :* 2009-10-11 21:57:40
> *� :* caml...@yquem.inria.fr
> *CC :*
> *Sujet :* Re: [Caml-list] Re: Improving OCaml's choice of type to display

Lukasz Stafiniak

unread,
Oct 11, 2009, 6:16:30 PM10/11/09
to Gilles Pirio, caml...@yquem.inria.fr
You need to use a type alias:

# type ('a, 'b) func = 'a -> 'b;;
type ('a, 'b) func = 'a -> 'b
# let castro a = (fun _ -> a : ('a,'b) func);;
val castro : 'a -> ('b, 'a) func = <fun>

This is also how the compiler decides the arity of C functions from
"external" declarations, that is, it "counts the arrows" without
unfolding type aliases.

On Sun, Oct 11, 2009 at 11:46 PM, Gilles Pirio
<gilles...@googlemail.com> wrote:
> Hey Damien
>
> Sure, I fully understand that both types are equivalent given the rules
> governing the application operator. My point was more on the usability side,
> as the type display is primarily intended at helping the programmer to
> quickly figure out type mismatch. So I'd think having a display allowing to
> quickly distinguish between the noe and castro functions below would be a
> good thing, especially for beginners. I've been using ocaml for a few years
> now, and I have to say that it's not a major issue any more - just wanted to
> give some feedback about this.
>
> Thanks
> Gilles
>
>
> # let noe a b = a;;
> val noe : 'a -> 'b -> 'a = <fun>
> # let castro a = fun _ -> a;;
> val castro : 'a -> 'b -> 'a = <fun>
>

_______________________________________________

Reply all
Reply to author
Forward
0 new messages