Skip to content

Allow appending and then dropping the same number of elements from Stream #608

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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion copilot-language/src/Copilot/Language/Analyze.hs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ analyzeAppend refStreams dstn e b f = do
-- append.
analyzeDrop :: Int -> Stream a -> IO ()
analyzeDrop k (Append xs _ _)
| k >= length xs = throw DropIndexOverflow
| k > length xs = throw DropIndexOverflow
| k > fromIntegral (maxBound :: DropIdx) = throw DropMaxViolation
| otherwise = return ()
analyzeDrop _ _ = throw DropAppliedToNonAppend
Expand Down
9 changes: 6 additions & 3 deletions copilot-language/src/Copilot/Language/Reify.hs
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,12 @@ mkExpr refMkId refStreams refMap = go
------------------------------------------------------

Drop k e1 -> case e1 of
Append _ _ _ -> do
s <- mkStream refMkId refStreams refMap e1
return $ Core.Drop typeOf (fromIntegral k) s
Append a _ s ->
if k == length a
then go s
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you include a comment here saying why we need a special case for k == length a? It wasn't obvious to me until I read the PR description.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Relatedly, I wonder if Copilot.Language.Reify if the right place to implement this transformation. Most of the simplifications that are performed over Drop streams are implemented in the drop function itself:

drop :: Typed a => Int -> Stream a -> Stream a
drop 0 s = s
drop _ ( Const j ) = Const j
drop i ( Drop j s ) = Drop (fromIntegral i + j) s
drop i s = Drop (fromIntegral i) s

Perhaps we should implement this transformation as an additional case of drop?

drop i ( Append a _ s ) | i == length a = s

Copy link
Member

@ivanperez-keera ivanperez-keera Mar 26, 2025

Choose a reason for hiding this comment

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

Not part of this issue, but that might be a good place to also do something like:

drop i (Op1 op s)     = Op1 op (drop i s)
drop i (Op2 op s1 s2) = Op2 op (drop i s1) (drop i s2)

Copy link
Author

@strikef strikef Mar 27, 2025

Choose a reason for hiding this comment

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

I agree that Reify module isn't the best place to implement this fix. The Temporal module you recommended looks better to me as well.

My initial intent of this change was getting correct C code (which is why I placed this fix at Reify module), and at that time simplification was just a 'nice' side-effect. But now that you mentioned, I don't see any reason to not treat it as simplification.
I'll move my fix to Temporal module and add explanatory comment as well.

Copy link
Author

Choose a reason for hiding this comment

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

Fixed as suggested

else do
_s <- mkStream refMkId refStreams refMap e1
return $ Core.Drop typeOf (fromIntegral k) _s
_ -> impossible "mkExpr" "copilot-language"

------------------------------------------------------
Expand Down