New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support empty record declaration #1536
Conversation
Signed-off-by: Runhang Li <marklrh@gmail.com>
Signed-off-by: Runhang Li <marklrh@gmail.com>
Signed-off-by: Runhang Li <marklrh@gmail.com>
Signed-off-by: Runhang Li <marklrh@gmail.com>
Signed-off-by: Runhang Li <marklrh@gmail.com>
Signed-off-by: Runhang Li <marklrh@gmail.com>
Signed-off-by: Runhang Li <marklrh@gmail.com>
@@ -1284,7 +1284,11 @@ and transl_record loc env fields repres opt_init_expr = | |||
match repres with | |||
| Record_regular -> Lconst(Const_block(0, cl)) | |||
| Record_inlined tag -> Lconst(Const_block(tag, cl)) | |||
| Record_unboxed _ -> Lconst(match cl with [v] -> v | _ -> assert false) | |||
| Record_unboxed _ -> Lconst( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the point of "unboxing" an empty record type, since the representation ends up being the same as the regular representation?
parsing/pprintast.ml
Outdated
@@ -1397,8 +1398,11 @@ and type_declaration ctxt f x = | |||
in | |||
match x.ptype_kind with | |||
| Ptype_variant xs -> | |||
pp f "%t%t@\n%a" intro priv | |||
(list ~sep:"@\n" constructor_declaration) xs | |||
if xs = [] then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is about empty variants, not empty records.
typing/oprint.ml
Outdated
fprintf ppf " =%a@;<1 2>%a" | ||
print_private td.otype_private | ||
(print_list print_out_constr (fun ppf -> fprintf ppf "@ | ")) constrs | ||
if constrs = [] then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also for empty variants, not records.
typing/typecore.ml
Outdated
None -> newvar (), None | ||
| None -> | ||
if lid_sexp_list = [] then begin | ||
match Env.find_empty_record env with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part could be shared with the similar addition type type_pat.
parsing/parser.mly
Outdated
@@ -1707,7 +1707,8 @@ expr_comma_list: | |||
| expr COMMA expr { [$3; $1] } | |||
; | |||
record_expr: | |||
simple_expr WITH lbl_expr_list { (Some $1, $3) } | |||
{ (None, []) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empty rules usually have /* empty */
in parser.mly.
@alainfrisch There are some changes about empty variants that I forgot to clean up. I will remove then address your comments next morning when I get up. |
parsing/parsetree.mli
Outdated
@@ -407,9 +407,7 @@ and type_declaration = | |||
and type_kind = | |||
| Ptype_abstract | |||
| Ptype_variant of constructor_declaration list | |||
(* Invariant: non-empty list *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment related to Ptype_variant
shouldn't be removed.
6ebbda6
to
07b4a17
Compare
At the last developers's meeting, there was consensus to support empty sum types, but empty record types were controversial. Have we really decided to support empty record types? Could we get a decision before spending more time reviewing and polishing this GPR? |
Hi, Xavier. I understand empty record is controversial but I'd like to open a PR just for some initial discussion. As for empty sum type, I noticed some cases my implementation does not handle. I am going to fix the problem soon. |
Ok, then I suppose that we should have a discussion. Basically, I see at least 2 ways to handle empty records without adding anything to the language:
Honestly I think that the first solution is sufficient: I cannot really imagine why you would want to make your empty record nominally distinct, as anyway it has no semantical contents. Regularity is nice, when it is really regular. Adding empty records as records requires modifications to the way we handle records that make me think that they are not regular records. |
The following code is already valid OCaml (and introduces isomorphic/nominally-distinct types): type s = []
type t = [] so it seems reasonable to allow the essentially equivalent code: type s = {}
type t = {} But since there are plenty of workarounds and a clear lack of enthusiasm it doesn't seem worth spending much more time on this. |
close this PR as it is deemed controversial |
This PR adds support of empty record declaration.
Support empty record declaration can
ocaml-pb
can generate proper code for empty protobuf message.See Mantis #7583 for more details.
Implementation in this PR might be inefficient during type-checking phase because we will search empty record declaration in environment in linear time complexity (instead of other
find-
methods inenv.ml
which will usePath.t
to do search in a AVL tree). That said, another approach is to allow{}
as user-defined constructor as we did in #234