Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: [Caml-list] Improving OCaml's choice of type to display
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Gilles Pirio <gilles.ocaml@g...>
Subject: Re: [Caml-list] Improving OCaml's choice of type to display
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 <alphablock@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-list@yquem.inria.fr
> *CC :*
> *Sujet :* Re: [Caml-list] Re: Improving OCaml's choice of type to display
>
>
> 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
>
>
> On Sun, Oct 11, 2009 at 8:24 AM, Jun Furuse <jun.furuse@gmail.com> wrote:
>
>> 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 <yminsky@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
>> > broken by length of final identifier.
>> >
>> > Y
>> >
>> > Yaron Minsky
>> >
>> > On Oct 11, 2009, at 10:57 AM, Jun Furuse <jun.furuse@gmail.com> wrote:
>> >
>> >> 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
>> >>
>> >> On Fri, Oct 9, 2009 at 10:53 AM, Yaron Minsky <yminsky@gmail.com>
>> wrote:
>> >>>
>> >>> 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
>> >>>
>> >>> On Thu, Oct 8, 2009 at 9:40 PM, Yaron Minsky <yminsky@gmail.com>
>> wrote:
>> >>>>
>> >>>> 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
>> >>>
>> >>>
>> >>> _______________________________________________
>> >>> 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
>> >>>
>> >>>
>> >
>>
>> _______________________________________________
>> 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
>>
>
>
> _______________________________________________
> 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
>
>