Skip to content

Add dropRight and takeRight#191

Closed
markus1189 wants to merge 1 commit intohaskell:masterfrom
markus1189:drop-take-right
Closed

Add dropRight and takeRight#191
markus1189 wants to merge 1 commit intohaskell:masterfrom
markus1189:drop-take-right

Conversation

@markus1189
Copy link
Copy Markdown
Contributor

I missed those functions recently and added them.

This was quite a bit of boilerplate 😞

@OlivierSohn
Copy link
Copy Markdown
Contributor

I suggest a change in names : dropEnd, takeEnd, I find it is less ambiguous than dropRight, takeRight (this is also the naming used in textpackage : http://hackage.haskell.org/package/text-1.2.2.1/docs/Data-Text.html#v:dropEnd)

@markus1189 markus1189 force-pushed the drop-take-right branch 2 times, most recently from 62b3b1b to 35277d8 Compare January 7, 2018 18:26
@markus1189
Copy link
Copy Markdown
Contributor Author

Sure, done!

@OlivierSohn
Copy link
Copy Markdown
Contributor

Should the unsafe versions be added, too? I see that for example take and drop have unsafe versions.

Comment thread Data/Vector/Generic.hs Outdated
where
n' = max n 0
m = length v
i = max 0 (m - n)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if n is negative? What about doing max 0 (m - n') instead? 😄

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Contributor

@OlivierSohn OlivierSohn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the code I read for dropand take functions, I think the use of delay_inline could be important to get the best possible optimizations. I might be wrong because I'm not familiar with fusion, but I think using the same approach as what in done in take and dropis a safe default.

EDIT : As I said in an earlier comment, it would be nice to have the unsafe versions too.

Comment thread Data/Vector/Generic.hs Outdated
-- contain less than @n@ elements in which case it is returned unchanged.
takeEnd :: Vector v a => Int -> v a -> v a
{-# INLINE_FUSED takeEnd #-}
takeEnd n v = unsafeSlice i (min n' m) v
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the use of delay_inline in takefunction, I think this should be:

unsafeSlice i (delay_inline min n' m) v

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread Data/Vector/Generic.hs Outdated
where
n' = max n 0
m = length v
i = max 0 (m - n)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the use of delay_inline in take function, I think this should be:

i = delay_inline max 0 (m-n')

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread Data/Vector/Generic.hs Outdated
-- contain less than @n@ elements in which case an empty vector is returned.
dropEnd :: Vector v a => Int -> v a -> v a
{-# INLINE_FUSED dropEnd #-}
dropEnd n v = unsafeSlice 0 (max 0 (m - n')) v
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here also, I think we need to add a delay_inline for the max

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread Data/Vector/Generic/Mutable.hs Outdated
where
n' = max n 0
m = length v
i = max 0 (m - n)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's safer to write max 0 (m-n')

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Done

model = V.toList
unmodel = V.fromList

naiveTakeEnd :: Int -> [a] -> [a]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test function is duplicated to be used in two files, I would rather put it in a separate module to avoid duplication, like the existing Utilitiesmodule.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to Utilities

naiveTakeEnd :: Int -> [a] -> [a]
naiveTakeEnd n = reverse . take n . reverse

naiveDropEnd :: Int -> [a] -> [a]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one, too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to Utilities

@markus1189
Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review! Next step is to add the unsafe versions as well then. I wish it would be less boilerplate-y though

@OlivierSohn
Copy link
Copy Markdown
Contributor

@markus1189 Yes, it looks like it will be a lot of copy / paste / change one word stuff :)

Maybe you can ask a maintainer of the library if it's necessary or not, before doing the work of adding the unsafe versions. (I'm not a maintainer myself)

@markus1189 markus1189 force-pushed the drop-take-right branch 2 times, most recently from 3b5c20c to 8b05a50 Compare January 11, 2018 07:49
@markus1189
Copy link
Copy Markdown
Contributor Author

I added the unsafe versions. I hope I did not make any copy & paste errors ;)

Comment thread Data/Vector/Generic/Mutable.hs Outdated

unsafeTakeEnd :: MVector v a => Int -> v s a -> v s a
{-# INLINE unsafeTakeEnd #-}
unsafeTakeEnd n v = unsafeSlice (m - n) m v
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the second argument is wrong I think, it should be n ?

Maybe adding tests for the unsafe versions would be a good idea (the same tests as for the safe ones)

Comment thread Data/Vector/Generic.hs Outdated
-- contain at least @n@ elements but this is not checked.
unsafeTakeEnd :: Vector v a => Int -> v a -> v a
{-# INLINE unsafeTakeEnd #-}
unsafeTakeEnd n v = unsafeSlice (m - n) m v
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too, m should be n

@markus1189
Copy link
Copy Markdown
Contributor Author

I am willing to continue to work on this, but before I do I would like to have some feedback from the maintainers whether this is wanted at all. 😉

@cartazio
Copy link
Copy Markdown
Contributor

cartazio commented Jan 17, 2018 via email

@markus1189
Copy link
Copy Markdown
Contributor Author

markus1189 commented Jan 18, 2018 via email

@cartazio
Copy link
Copy Markdown
Contributor

cartazio commented Jan 18, 2018 via email

@markus1189 markus1189 force-pushed the drop-take-right branch 2 times, most recently from 153bb8e to 90dd307 Compare January 19, 2018 14:44
@markus1189
Copy link
Copy Markdown
Contributor Author

I kind of gave up on writing the prop for the naive version. It seems like there is quite some customizing going on in the QuickCheck tests.

Some help would be great there ;)

@OlivierSohn Fixed the issues you raised, thanks a lot for the in-depth reviews!

@cartazio
Copy link
Copy Markdown
Contributor

possibly dumb question, and this might just be me missing a difference ... but how is takeEnd different from drop?, just a difference in in counting from front of vector vs end of vector?

this seems to be a useful difference, and the key one that motivates the changes?

@cartazio
Copy link
Copy Markdown
Contributor

so one possible question about this for code simplification: is there any reason to not define takeEnd in terms of drop, and dropEnd in terms of take? (one reason not to would be if the generated core was less awesome under O2 or something)

@cartazio
Copy link
Copy Markdown
Contributor

also you duplicated an Orphan, https://travis-ci.org/haskell/vector/jobs/330841124#L908-L918
use the orphan module for that

Comment thread tests/Tests/Vector.hs Outdated
-- TODO: test non-IVector stuff?

#if !MIN_VERSION_base(4,7,0)
instance Foldable ((,) a) where
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ORPHAN, see Data.Orphan in tests

@markus1189
Copy link
Copy Markdown
Contributor Author

@cartazio Yes indeed, takeEnd is drop but avoids the calculation of correct offsets (equivalently for take and dropEnd)

I missed those handy functions recently and thought to add them (this was in 24pullrequests btw :) )

This got a little out of hand, I thought it would be much less stuff to do, though 😉

Will check the orphans

@cartazio
Copy link
Copy Markdown
Contributor

I guess my point is that if those overheads/extra calculations are optimized away under O2 level optimization and have equivalent fusion characteristics, may as well do the simpler definition in terms of preexisting high level operations. I would be surprised if the optimized core isn't essentially the same. (worth a bug report even :) )

@OlivierSohn
Copy link
Copy Markdown
Contributor

OlivierSohn commented Jan 21, 2018

also you duplicated an Orphan, https://travis-ci.org/haskell/vector/jobs/330841124#L908-L918
use the orphan module for that

I see the same error on my pull request #196, strange... is it possible to launch a build of master to see if the build is still ok?

@cartazio
Copy link
Copy Markdown
Contributor

@cartazio
Copy link
Copy Markdown
Contributor

master is fine, this patch is the issue :)

@cartazio
Copy link
Copy Markdown
Contributor

i restarted the PR build so we can look again

@markus1189
Copy link
Copy Markdown
Contributor Author

Sorry but I have to abandon this as I don't come around to do it. If anyone wants to pick it up, feel free ;)

@noughtmare
Copy link
Copy Markdown

noughtmare commented Dec 21, 2022

I think it would bo good to consider using the names dropL, dropR, takeL, and takeR (like what the Data.Sequence module in the containers library does). Because vectors have no inherent bias to left or right (except perhaps the fusion mechanism?). Text (and arguably bytestrings) do have such a bias, so the asymmetric naming scheme makes sense for those types.

@lehins
Copy link
Copy Markdown
Contributor

lehins commented Dec 22, 2022

@noughtmare Would you like to create an issue with a link to this PR, so it doesn't get forgotten and someone with time on their hands can pick it up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants