Skip to content

Parameter order of linear collections #147

@utdemir

Description

@utdemir

Currently, most of our linear collections (Array, Vector.Mutable and HashMap) take the collection as a first argument. Here are some examples from linear base:

Data.Array.Mutable.Linear.write :: HasCallStack => Array a #-> Int -> a -> Array a
Data.Vector.Mutable.Linear.write :: HasCallStack => Vector a #-> Int -> a -> Vector a

This is also what vector library does.

But there are also places where we do the opposite:

Data.Array.Mutable.Linear.resize :: HasCallStack => Int -> Array a #-> Array a
Data.Array.Polarized.Pull.foldr :: (a #-> b #-> b) -> b #-> Array a #-> b
Data.Array.Destination.split :: Int -> DArray a #-> (DArray a, DArray a)

(Also, as expected, the functions we re-implemented from base also tend to take the collection as the last argument)


I think, taking the collection as the last parameter has some benefits:

  • I believe most libraries are using the collection-last argument order.
  • It makes point-free usage nicer (vec & write 0 'a' & write 1 'c')
  • Usually our functions are linear on the collection, and not on the rest. So, a type signature like:
write :: Int -> a -> Array a #-> Array a

Makes it clear that "given an Int and an a that we're linearly transforming an Array to another". The alternative:

write :: Array a #-> Int -> a -> Array a

In my opinion does not read as well, the unrestricted arrow before the result gives me the wrong impression.

The disadvantages I can think of:

  • Differing from the vector library.
  • We have to change some amount of code.

No matter which order we choose, it would be good to stick to it across the codebase.

This issue is broken up from the original PR: #146

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions