Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0006806OCaml~DO NOT USE (was: OCaml general)public2015-03-10 22:502017-02-16 15:16
Reportersliquister 
Assigned Todim 
PrioritynormalSeverityfeatureReproducibilityhave not tried
StatusclosedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version4.03.0+dev / +beta1 
Summary0006806: Syntax shortcut for putting a type annotation on a record field
DescriptionI'd like the syntax for record literals to be extended so one can write:

{ f1 : typ = e } to mean { f1 = (e : typ) }
{ f1 : typ } to mean { f1 = (f1 : typ) }

(see attached patch)
This is because I have a preprocessor that transforms a restricted subset
of expressions (mostly data constructors) into sexps, but any expression
can be used provided its type is given.
So we frequently end up writing things like:

<:structural_sexp< { a = (a : int); b = (b : int) } >>

which I would prefer to write:

<:structural_sexp< { a : int; b : int } >>

(which of course I could do myself with camlp4 right now but not when it becomes a ppx rewriter)
TagsNo tags attached.
Attached Files? file icon patch [^] (1,154 bytes) 2015-03-10 22:50 [Show Content]
? file icon patch-v2 [^] (1,859 bytes) 2015-03-12 16:55 [Show Content]
? file icon patch-v2+fun [^] (2,150 bytes) 2015-03-12 18:49 [Show Content]
? file icon patch-v3 [^] (2,695 bytes) 2015-08-26 18:53 [Show Content]
? file icon patch-annot-fun-return [^] (982 bytes) 2015-08-26 18:53 [Show Content]

- Relationships
related to 0006800confirmed simplify using gadt with lambda 

-  Notes
(0013428)
gasche (administrator)
2015-03-11 08:09

Looks very reasonable to me.
(0013429)
frisch (developer)
2015-03-11 09:57

I like it too, it's very coherent with "let x : t = e" or "module X : S = E".
(0013442)
sliquister (reporter)
2015-03-11 13:59

(as a side effect of reusing the "type_constraint" nonterminal, the patch also adds the other forms { a :> int } and { a : int :> int }, which are also allowed on let bindings:
# let x :> [ `A | `B ] = (`A : [ `A ]);;
val x : [ `A | `B ] = `A
# let x : [ `A ] :> [ `A | `B ] = `A;;
val x : [ `A | `B ] = `A
)
(0013456)
garrigue (manager)
2015-03-12 01:08

I have mixed feelings on this one.
On the one hand, this is coherent with the rest of the language, in particular labeled arguments.
On the other hand, records are defined, so usually there is no need for type annotations there...
Also, the patch is only for expressions. One would expect the same behavior in patterns (should be easy).
(0013477)
sliquister (reporter)
2015-03-12 17:03

You're right, I attached a new patch:

# fun { contents : int } -> contents;;
- : int ref -> int = <fun>

And yes I agree type annotations are not super useful on records in general, that's why I explained why I wanted this piece of syntax. There could be cases like with references where the record is polymorphic in some fields but that's not too common.


While I was there I tried adding a type annotation before the "->" of "fun" (as mentioned in some other issue), but there is a conflict between the arrow in the construct and the one in types ("fun x : int -> int"), so I stopped there instead of figuring out how to convince the parser to reduce.
(0013478)
gasche (administrator)
2015-03-12 17:35

It's very nice of you to work on this. You should use the class 'simple_core_type' (which does not allow "foo -> bar" unparenthesized) rather than 'core_type'.
(0013481)
sliquister (reporter)
2015-03-12 18:51

Fair enough, I added it (in the same patch as the other changes but the one line could be extracted).
(0014374)
sliquister (reporter)
2015-08-23 04:23

Any chance the patch can go in, in the end?
(0014378)
gasche (administrator)
2015-08-24 16:45

Thanks for the reminder.

I think these are two separate changes that should go in two separate patches.

Besides, I would like to see the new syntax introduced exercised somewhere in the testsuite. Could you convert some, but not all, uses of (fun .. -> (x : ..)) to the new syntax (for example the one in typing-warnings/coercions.ml), and add the record syntax to tests/exotic-syntax/exotic.ml?
(0014387)
garrigue (manager)
2015-08-25 05:09

Honestly, I'm not yet convinced of how much useful it is.
Did we have a discussion about the need to be able to write type annotations in every special compact form? Particularly when the type can actually be inferred?
For records usually the type annotation would go on the whole record, not on a specific field.

Note that some people already have preprocessors that work after type-checking, and eventually we will probably have a standard way to do that.
(0014388)
gasche (administrator)
2015-08-25 08:26

On the other hand, it serves a clearly expressed user purpose now (whereas there is no time estimation for when typedtree will be usable enough for non-experts to process), and it is a very simple patch, which does not significantly increase the complexity of the parser -- the only show-stopper would be if it added conflicts, but I assume that sliquister checked and that it did not. I would rather be in favor of merging (why not?).

I am under the impression that there is consensus that the other part of the change that sliquister included in the same patch, (fun x y : foo -> e) as a synonym of (fun x y -> (e : foo)), is very useful. At least there was in the last GADT discussion where this feature was evoked.
(0014390)
lpw25 (developer)
2015-08-25 14:46

The difference between let bindings and record field bindings frequently annoys me (the other aspect is not being able to write function field definitions like `{ f x = x }`), so I'm in favour of this change.

It is not hugely useful, but it has a low cost and improves the consistency of the syntax.
(0014391)
sliquister (reporter)
2015-08-25 15:33

To be clear, there is no record type corresponding to the record expression. So a post-typing hook wouldn't work, since the code wouldn't type to begin with. Perhaps a hook during typing on uninterpreted extension would work, by synthetizing the record definition, but it comes with the problem of ambiguity, since not all types that unify are serialized the same way.
Not having a record type is most of the interest of the syntax extensions, since they would be one off definitions.
(0014406)
sliquister (reporter)
2015-08-26 18:59

I added the tests you suggested and split the two changes.
(0014641)
dim (developer)
2015-11-04 14:36

> For records usually the type annotation would go on the whole record, not on a specific field.

Now that type annotations are used for disambiguation I think it's useful to be able to put annotations in more places. I recently wrote some code where I put a type annotation on a specific field in a record pattern. It was possible to put the annotation on the whole record pattern but it was heavier.

On another note the syntax is already relaxed in other places that don't make sense for OCaml but might for ppx rewriters. For instance you can write "for a, b = ..." which is accepted by the parser but later rejected by the typer. This change is useful for both ppx rewriters and regular OCaml, so it's one more reason to accept it.

Unless other objections I'm planning to merge the patches.
(0014643)
gasche (administrator)
2015-11-04 16:04

Thanks!
(0014646)
dim (developer)
2015-11-05 11:43

I merged the two patches in trunk:

https://github.com/ocaml/ocaml/commit/26657d5736b1b663072ea9ca17957875b909286d [^]
https://github.com/ocaml/ocaml/commit/6676784f6320aa9e415261fca1154c5447fa7a13 [^]

- Issue History
Date Modified Username Field Change
2015-03-10 22:50 sliquister New Issue
2015-03-10 22:50 sliquister File Added: patch
2015-03-11 08:09 gasche Note Added: 0013428
2015-03-11 09:57 frisch Note Added: 0013429
2015-03-11 13:59 sliquister Note Added: 0013442
2015-03-12 01:08 garrigue Note Added: 0013456
2015-03-12 16:55 sliquister File Added: patch-v2
2015-03-12 17:03 sliquister Note Added: 0013477
2015-03-12 17:35 gasche Note Added: 0013478
2015-03-12 18:49 sliquister File Added: patch-v2+fun
2015-03-12 18:51 sliquister Note Added: 0013481
2015-05-05 23:01 doligez Status new => acknowledged
2015-08-23 04:23 sliquister Note Added: 0014374
2015-08-24 16:45 gasche Note Added: 0014378
2015-08-25 05:09 garrigue Note Added: 0014387
2015-08-25 08:26 gasche Note Added: 0014388
2015-08-25 14:46 lpw25 Note Added: 0014390
2015-08-25 15:33 sliquister Note Added: 0014391
2015-08-26 18:53 sliquister File Added: patch-v3
2015-08-26 18:53 sliquister File Added: patch-annot-fun-return
2015-08-26 18:59 sliquister Note Added: 0014406
2015-11-04 14:36 dim Note Added: 0014641
2015-11-04 16:04 gasche Note Added: 0014643
2015-11-05 11:43 dim Note Added: 0014646
2015-11-05 11:43 dim Assigned To => dim
2015-11-05 11:43 dim Status acknowledged => assigned
2015-11-05 11:43 dim Status assigned => resolved
2015-11-05 11:43 dim Fixed in Version => 4.03.0+dev / +beta1
2015-11-05 11:43 dim Resolution open => fixed
2015-12-02 16:29 frisch Relationship added related to 0006800
2017-02-16 15:16 xleroy Status resolved => closed
2017-02-23 16:36 doligez Category OCaml general => -OCaml general
2017-03-03 17:55 doligez Category -OCaml general => -(deprecated) general
2017-03-03 18:01 doligez Category -(deprecated) general => ~deprecated (was: OCaml general)
2017-03-06 17:04 doligez Category ~deprecated (was: OCaml general) => ~DO NOT USE (was: OCaml general)


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker