haskell / vector

An efficient implementation of Int-indexed arrays (both mutable and immutable), with a powerful loop optimisation framework .
Other
366 stars 139 forks source link

Adding more `HasCallStack` s #494

Open toyboot4e opened 5 months ago

toyboot4e commented 5 months ago

I suggest adding more HasCallStack constraints.

1. Missing HasCallStack constraints

Some functions in non- Generic modules are missing HasCallStack constraints.

Example: VU.(!)

VU.(!) does not have HasCallStack constraint and we don't get full trace:

Example ```hs {- stack script --resolver lts-22.24 --package vector -} import Data.Vector.Unboxed qualified as VU main :: IO () main = do let !_ = (VU.fromList [0 :: Int]) VU.! 42 return () ``` The call stack does not contain `VU.(!)` call from `main`: ```sh $ stack example-u.hs example-u.hs: index out of bounds (42,1) CallStack (from HasCallStack): error, called at src/Data/Vector/Internal/Check.hs:103:12 in vector-0.13.1.0-Aqc2YUE1Egs5WmXVMbcJ5T:Data.Vector.Internal.Check checkError, called at src/Data/Vector/Internal/Check.hs:109:17 in vector-0.13.1.0-Aqc2YUE1Egs5WmXVMbcJ5T:Data.Vector.Internal.Check check, called at src/Data/Vector/Internal/Check.hs:122:5 in vector-0.13.1.0-Aqc2YUE1Egs5WmXVMbcJ5T:Data.Vector.Internal.Check checkIndex, called at src/Data/Vector/Generic.hs:235:11 in vector-0.13.1.0-Aqc2YUE1Egs5WmXVMbcJ5T:Data.Vector.Generic !, called at src/Data/Vector/Unboxed.hs:297:7 in vector-0.13.1.0-Aqc2YUE1Egs5WmXVMbcJ5T:Data.Vector.Unboxed ```

VG.(!) has HasCallStack constraint and we get a full trace:

Example ```diff {- stack script --resolver lts-22.24 --package vector -} import Data.Vector.Unboxed qualified as VU +import Data.Vector.Generic qualified as VG main :: IO () main = do - let !_ = (VU.fromList [0 :: Int]) VU.! 42 + let !_ = (VU.fromList [0 :: Int]) VG.! 42 return () ``` The call stack contains `VG.(!)` call from `main`: ```sh $ stack example-g.hs example-g.hs: index out of bounds (42,1) CallStack (from HasCallStack): error, called at src/Data/Vector/Internal/Check.hs:103:12 in vector-0.13.1.0-Aqc2YUE1Egs5WmXVMbcJ5T:Data.Vector.Internal.Check checkError, called at src/Data/Vector/Internal/Check.hs:109:17 in vector-0.13.1.0-Aqc2YUE1Egs5WmXVMbcJ5T:Data.Vector.Internal.Check check, called at src/Data/Vector/Internal/Check.hs:122:5 in vector-0.13.1.0-Aqc2YUE1Egs5WmXVMbcJ5T:Data.Vector.Internal.Check checkIndex, called at src/Data/Vector/Generic.hs:235:11 in vector-0.13.1.0-Aqc2YUE1Egs5WmXVMbcJ5T:Data.Vector.Generic !, called at /home/tbm/dev/hs/tmp/example-g.hs:8:37 in main:Main ```

2. head and more

I personally like to add HasCallStack to anywhere possible.

For example, the head function does not have HasCallStack constraint. But the list's head function in base doesn't have it either. What do you think? Thank you.

toyboot4e commented 5 months ago

Oh no, it was already discussed A LOT in the Haskell community (outside of the vector repository). Closing as the impact seems bigger than I expected.

Shimuuar commented 5 months ago

Could you provide links to discussions? Adding HasCallStack to functions which could fail with out of range exception seems quite sensible to me.

toyboot4e commented 5 months ago

Thank you, I rushed. Let me share the links.


Past PR:

Compilation time, memory usage, runtime performance:

Related:


My notes: