I have some objects that I want to give a compile time id, something like:
Blah.create ~id:`MyId
I’d like a way to use integers if possible, but have the ergonomics of strings/polymorphic variants. The polymorphic variants seem to pollute the code with a lot of type variables to hold the list of used IDs (I’m not sure of a good way to hide, then compare them?). And I’d like to avoid doing string comparisons between IDs all the time.
Slightly more example code:
type obj1 = <
id : int; (* Ideally, or something opaque and simple *)
text : string;
>
type obj2 = <
id : int;
text : string;
click : unit -> unit;
>
let obj1 : obj1 = Text.create ~id:`TxtHello ~text:"Hello World" in
let obj2 : obj2 = Button.create ~id:`BtnClick ~text:"Click" ~handler:(fun ...) in
...
I’d also like to avoid having to pre-allocate a bunch of id’s and avoid having a giant variant with all possible ids. Is there any kind of variant -> int ?
But, there is no guarantee that they will be unique between different Texts and Buttons.
It’s much less ergonomic, and I’m making this suggestion without full context of what you want to do, but it might be worth taking a look at Base.Type_equal.{Id,Uid}.
Ah, that may be all I need! The IDs being global between controls is more or less what I want right now. There’s a later part of the system that erases the specifics with object subtyping, and operates on generic controls, but still needs IDs. The IDs are mostly to say “these are semantically the same element”. There’s a diff between two control layouts and the IDs help track what changed.
No PPX jock I. But I remember there was an example using “getenv”, where the getenv happened at compile-time. I can only imagine that it would be child’s play to concatenate process-id and current-time-in-nanos to get a unique ID, again at compile-time.
Note that objects automatically come with integer identities. That is, you can compare them with = and sort them with <, etc. You can get access to this ID with Oo.id:
e.g.
utop # let a = object end;;
val a : < > = <obj>
utop # let b = object end;;
val b : < > = <obj>
utop # a = a;;
- : bool = true
utop # a = b;;
- : bool = false
utop # Oo.id a;;
- : int = 143
utop # Oo.id b;;
- : int = 145