Skip to content
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

Private arrays #8927

Open
mjambon opened this issue Sep 8, 2019 · 5 comments

Comments

@mjambon
Copy link

commented Sep 8, 2019

I have a use case where private arrays would be useful. The use case is similar to uses of private records with mutable fields. It allows the user to read certain details without being able to mutate the data structure. Only the module in charge of creating and maintaining the data structure is allowed to modify it (or create it).

For example, I have a module that exposes an array of names:

type t
val names : t -> string array

The names function returns the same physical array every time. It would nice to ensure the user won't try to change the names by assigning to this array. It would also be nice to achieve this without having to create a custom read-only interface to the array, such as val name : t -> int -> string because it's not clear to the user how efficient this is. In such case we could add documentation explaining name t i is just a read from an array, but it's not as clear as having names.(i) right in the user's code.

So, I think it would be nice to have private support for arrays, like this:

type t
type names = private string array
val names : t -> names

I don't know the technical difficulties involved. For me it's merely a wish for a nice-to-have feature, and it seems consistent with the behavior of private records with mutable fields (which I already use generously).

@yminsky

This comment has been minimized.

Copy link

commented Sep 8, 2019

What's the advantage of doing this in the language, vs implementing the same thing with abstract types, e.g.:

https://github.com/janestreet/core_kernel/blob/master/src/array.mli#L78

I think of the key value of private is that it preserves the specialized pattern-matching syntax without having to give full access to writing values; but there's much less value in pattern matching in arrays, I would have thought.

Also, I think this is not really the same feature as private records, since I assume the private string array you refer to wouldn't actually be a new nominal type.

@mjambon

This comment has been minimized.

Copy link
Author

commented Sep 8, 2019

The advantage of having this in the language is simplicity for the user (of a library that uses the feature). What I can see is:

  • the a.(b) syntax remains available;
  • no need for extra documentation.

I understand that type t' = private string t already means something else and that array is not special in that respect. However, I don't expect a user to understand that, and seeing an array as variable-length record isn't far-fetched:

type 'a point3 = {
  mutable x : 'a;
  mutable y : 'a;
  mutable z : 'a
}

(* Here's our hypothetical record with unconstrained length *)
type 'a point = [|
  mutable x : 'a;
|]

In a hypothetical language, having the syntax type t = private [| mutable string |] doesn't seem absurd. The compiler could deal with the fact that the constructor private [| has special properties that relate to the constructor [|. This is to say that it's unfortunate that array is treated like any other type name rather than a special constructor.

@jberdine

This comment has been minimized.

Copy link

commented Sep 8, 2019

Related, but perhaps not quite the same: I have wanted a type that serves as an immutable view of a value represented by an array. This seems close to the same as a private array type, except that constructing literals (using the [| |] array syntax, say) is ok for an immutable view but not for a private alias. The sticking point I hit, which might be possible using more wizardry than I know, was how to define an immutable array type that both is covariant and represented as an array. (If it matters, the covariance has been needed only for phantom type parameters.)

@lpw25

This comment has been minimized.

Copy link
Contributor

commented Sep 9, 2019

#616 implements this feature. I still hope to get that merged at some point.

@mjambon

This comment has been minimized.

Copy link
Author

commented Sep 9, 2019

@lpw25 I wasn't aware of this work. I find it very elegant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.