Skip to content

Conversation

Shimuuar
Copy link
Contributor

@Shimuuar Shimuuar commented Sep 3, 2025

This is proof of concept implementation of #535 for primitive vectors.

Idea work out nicely. There's one small complication. It makes sense to define unsafe function working on representation of a vector but we get name clashes: both mutable and pure primitive vectors defined unsafeCast so it pprobab;y makes sense to keep such function where they're currently defined

Reviews are very welcome.

Fixes #535, Fixes #524, Fixes #517, Fixes #506, Fixes #492, Fixes #171

@lehins
Copy link
Contributor

lehins commented Sep 3, 2025

both mutable and pure primitive vectors defined unsafeCast

I think it would make sense to add an Data.Primitive.Unsafe and Data.Primitive.Mutable.Unsafe modules to separate the concerns. This is what I was suggesting in #361 which was scrapped. But, considering that this idea is coming up again and again, maybe it is a good idea after all?

@Shimuuar
Copy link
Contributor Author

Shimuuar commented Sep 5, 2025

Yes it seems in the end library authors need to provide access to internals and it's better to do it systematic way. I hoped to get away with single Unsafe module but looks like 2 are needed.

@Shimuuar Shimuuar mentioned this pull request Sep 14, 2025
@Shimuuar Shimuuar force-pushed the unsafe-constructor branch 2 times, most recently from e7237e3 to 32c7585 Compare September 18, 2025 18:44
@Shimuuar
Copy link
Contributor Author

I implemented unsafe modules for everything except Unboxed. It's quite a bit different from other vectors and still require some cleanup. Haddocks are not ready either

General idea is to move definition of data type and all function that work directly on vector representation into Unsafe module. It has nice side effect of separating code specific to vector type from endless specializations.

At the moment all function safe and unsafe are simply reexported from safe modules. Deprecation warning is only applied to pattern synonym.

@Shimuuar
Copy link
Contributor Author

Shimuuar commented Oct 3, 2025

Now PR is mostly done. Implementation follows rules below:

  • For all vector types except unboxed. Two Unsafe modules are added. They provide access to constuctors. All function what work on internal representation are defined there. Exported constructors from safe modules are replaced with deprecated pattern synonyms.
  • For unboxed vectors. Data.Vector.Unboxed.Base renamed to Data.Vector.Unboxed.Unsafe. All constructors for data instances which are safe to expose are exposed (both mutable and immutable). These are newtype wrappers over vector representation. Exports of unsafe constructors

Remaining questions

  1. Right now only constructors are deprecated. Do we want to deprecate unsafe functions as well? (unsafe{From,To}ForeignPtr0, unsafeCoerceMVector, unsafeCast, etc) now they are simply reexported from "safe" modules.

  2. Renaming Data.Vector.Unboxed.BaseData.Vector.Unboxed.Unsafe is breaking change I think. However I want to rework size hints in bundles. And that will be breaking change anyway

  3. New modules are not documented properly yet.

We have 3 sorts of data instances:

 1. Constructors that we must exports. Data instances which are used in deriving
    via (UnboxViaPrim etc.). When constructors aren't visible deriving won't
    work. They were exported before.

 2. Constructors which are safe to use. Newtype vectors over underlying
    representation. Now they're exported from both immutable and mutable

 3. Dangerous and unsafe ones: tuple and unit instances. They're exported from
    Unsafe module. Mutable module reexports deprecated pattern synonym.
@Shimuuar Shimuuar force-pushed the unsafe-constructor branch from 6e2ceb8 to a44dfb1 Compare October 3, 2025 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants