From: Alain Frisch <frisch@clipper.ens.fr>
To: Jeff Henrikson <jehenrik@yahoo.com>
Cc: <caml-list@inria.fr>
Subject: Re: [Caml-list] record labels of record scope using camlp4
Date: Mon, 14 Jan 2002 13:15:04 +0100 (MET) [thread overview]
Message-ID: <Pine.GSO.4.33.0201141242570.12723-100000@clipper.ens.fr> (raw)
In-Reply-To: <000101c19ccc$ffe8e8c0$0b01a8c0@mit.edu>
On Mon, 14 Jan 2002, Jeff Henrikson wrote:
> It seems like a lot of people dislike the fact that record labels have
> module scope instead of record scope.
I think it should be possible to minimize the incovenience without
rejecting module scope. For instance, one could introduce the syntax:
module_path.{ x1 = e1; ....; xn = en }
as an abbreviation for:
{ module_path.x1 = e1; ...; module_path.xn = en }
Another way would be to use type information provided by the type-checker.
For accessing field, here is a description of a simple patch to the
type-checker that could be handy; the idea is that, when the expression e
is known to be a record of a given type, one can use a "record scope" rule
for label. A ten-minutes hack leads me to:
in typing/types.{ml,mli}:
...
and type_kind =
Type_abstract
| Type_variant of (string * type_expr list) list
| Type_record of (string * mutable_flag * type_expr * label_description
option ref) list * record_representation
...
(note the extra (dirty) label_description option ref)
and trivial modification in many places ...
in typing/datarepr.ml:
let label_descrs ty_res lbls repres =
let all_labels = Array.create (List.length lbls) dummy_label in
let rec describe_labels num = function
[] -> []
| (name, mut_flag, ty_arg, l) :: rest ->
let lbl =
{ lbl_res = ty_res;
lbl_arg = ty_arg;
lbl_mut = mut_flag;
lbl_pos = num;
lbl_all = all_labels;
lbl_repres = repres } in
(match !l with
| Some _ -> () (* Note sure what this corresponds to *)
| None -> l := Some lbl);
all_labels.(num) <- lbl;
(name, lbl) :: describe_labels (num+1) rest in
describe_labels 0 lbls
in typing/typedecl.ml:
| Ptype_record lbls ->
let all_labels = ref StringSet.empty in
List.iter
(fun (name, mut, arg) ->
if StringSet.mem name !all_labels then
raise(Error(sdecl.ptype_loc, Duplicate_label name));
all_labels := StringSet.add name !all_labels)
lbls;
let lbls' =
List.map
(fun (name, mut, arg) ->
(name, mut, transl_simple_type env true arg, ref
None))
lbls in
let rep =
if List.for_all (fun (name, mut, arg, _) -> is_float env
arg) lbls
'
then Record_float
else Record_regular in
Type_record(lbls', rep)
end;
type_manifest =
(note the extra ref None)
in typing/typecore.ml (function type_exp):
| Pexp_field(sarg, lid) ->
let arg = type_exp env sarg in
let label =
try
try
match lid with
| Longident.Lident name -> lookup_label arg.exp_type name env
| _ -> raise Not_found
with Not_found -> Env.lookup_label lid env
with Not_found ->
raise(Error(sexp.pexp_loc, Unbound_label lid)) in
let (ty_arg, ty_res) = instance_label label in
where lookup_label is defined as:
let rec lookup_label ty name env =
let ty = repr ty in
match ty.desc with
| Tconstr (path, _, _) ->
let td = Env.find_type path env in
begin match td.type_kind with
| Type_record (fields, _) ->
let (_,_,_,l) =
List.find (fun (name', _, _,_) -> name = name') fields in
(match !l with
Some l -> l
| None -> raise Not_found)
| Type_abstract when td.type_manifest <> None ->
lookup_label (expand_head env ty) name env
| _ -> raise Not_found
end
| _ ->
raise Not_found
This patch allows to write things like:
type t = { x : int; y : int };;
type s = { x : string };;
let f (t : t) : int = t.x;;
The same could be done for record expression (in function type_expect):
let r : t = { x = 2; y = 3 } in
...
On the one hand, this kind of interaction with the type-checker is quite
dangerous as it breaks complete type inference, but in OCaml, there are
already some cases where type annotations are mandatory; on the other
hand, it leads to a lightweight syntax and is probably what programmers
expect.
(sorry for suggesting a solution to a non-issue ;) )
--
Alain
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
next prev parent reply other threads:[~2002-01-14 12:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-01-14 7:28 Jeff Henrikson
2002-01-14 10:01 ` Daniel de Rauglaudre
2002-01-14 12:15 ` Alain Frisch [this message]
2002-01-17 18:06 ` Didier Remy
2002-01-17 19:58 ` Alain Frisch
2002-01-18 6:58 ` Jacques Garrigue
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.GSO.4.33.0201141242570.12723-100000@clipper.ens.fr \
--to=frisch@clipper.ens.fr \
--cc=caml-list@inria.fr \
--cc=jehenrik@yahoo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox