-
Notifications
You must be signed in to change notification settings - Fork 40
(Camlinternal)Uniform_array: minimal support for uniform arrays
#37
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
base: master
Are you sure you want to change the base?
Conversation
|
I'd suggest to look into type item = DummyA | DummyB | DummyC of int
let _ = [DummyA; DummyB; DummyC 0] (* to avoid warnings *)
let dummy_item = (Obj.magic () : item)Why not just |
|
Thanks for the pointer. From looking at it briefly, I cannot tell whether I would recommend trying to use explicit uniform arrays for this purpose. The "methods" array seems to be a bytecode array with a mix of methods and arguments (so indeed uniform arrays would be a good choice here). The
Git suggests that this is a historic artifact, before those constructors were introduced (What I cannot tell is what |
|
Coming back to the proposal: I don't see the point on insisting on a particular tag: |
Currently translprim.ml has: I would propose to add just 5 extra lines of code:
Yes, this is the idea. My idea would be to specialize primitives to carve out less-smart versions, so the amount of new code should be very small in any case.
For now I am not really interested in extending the proposal to explicitly cover non-standard tag choices, which sound a bit dubious to me. If the implementation naturally allows them I will look the other way. |
I don't think you need them. On all platforms for which we support the native compiler, But I guess that shows the difference in how we see this: you seem to want a full-fledged data structure with compiler support, I just want a decent way to manipulate dynamically sized blocks full of values. |
|
This looks very useful to have to increase legibility and safety in the important use cases you mention. I can also imagine cases when I’d want to enforce absence of allocation in some hot paths. |
|
Coq/Rocq also includes a small module of uniform arrays in its codebase, as part of the definition of its "persistent arrays": https://github.com/coq/coq/blob/d7d392191a367839b0f5a7772e48b8f24e9f1b3e/kernel/parray.ml . My understanding is that the need for uniformity arises from the compilation scheme of |
|
I'm not sure if we want uniform arrays or immutable uniform arrays (or both). |
|
Happily, literals should not be a problem now that we have type-disambiguated array literals! |
|
I am still in favor of this. For the record, Jane Street’s
We definitely want at least uniform mutable arrays as they would be useful to simplify the implementation of the Dynarray module. I don’t see a big reason to have immutable uniform arrays, but I also don’t see a reason not to have them if a use case shows up. |
|
I'm in favor. |
|
Is there no future where the uniform representation, already available by a configure flag, becomes the only supported mode? It removes complexity (in the runtime and type system), makes generic array accesses faster, and avoids the need for this new module. |
|
Such a future exists, but the path that I personally see toward it is to make |
|
For what it’s worth, I agree with @gasche there. We’re on a similar journey within Jane Street. We could, at any time, just turn off the flat-float-array-optimization in the compiler we use to build our apps. But it would degrade the performance of the many But regardless of which approach, we need to build a viable alternative to |
|
My 2cts: we can survive a while in Rocq with our own Obj.magic-based uniform arrays, the real issue about float arrays is that it pervades the runtime and makes a lot of untyped code dangerous for VM / native / extraction due to semantic concerns. I'm sure I'm rehashing a problem well-known by the runtime experts, but basically if you define OCaml types as semantic predicates on values, then all types A must satisfy the property that if v ∈ A for some float v, then all w ∈ A are floats. In particular, this implies that |
Reading this comment made me realise that the stdlib's Array.Floatarray module is unnecessarily restricted, and could be implemented as follows instead, giving it a more general signature: module Floatarray = struct
type 'a t
module Create (X : sig type t = private float end) = struct
external create : int -> X.t t = "caml_floatarray_create"
end
include Create (struct type t = float end)
external length : 'a t -> int = "%floatarray_length"
external get : 'a t -> int -> 'a = "%floatarray_safe_get"
external set : 'a t -> int -> 'a -> unit = "%floatarray_safe_set"
external unsafe_get : 'a t -> int -> 'a = "%floatarray_unsafe_get"
external unsafe_set : 'a t -> int -> 'a -> unit
= "%floatarray_unsafe_set"
endThis interface allows code to manipulate |
This RFC proposes to add minimal support in the OCaml implementation for uniform arrays, which always use the standard
Array_tagrepresentation and neverDouble_array_tag.The compiler would offer specialized built-in and C primitives to work with uniform arrays, and a minimal
CamlinternalUniform_arraymodule in the standard library exposing these primitives.This would make it easier to write some unsafe idioms that enforce uniform arrays in more complex ways today, simplifying the code of
Domain.DLS, the unboxed implementation ofDynarray, and theUniform_arraymodule of Jane Street's Base library and making it easier to reason about their correctness.Full version, rendered.