Skip to content
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

Add Delay type and use it #5910

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Add Delay type and use it #5910

wants to merge 3 commits into from

Conversation

michaelpj
Copy link
Contributor

Fixes #5908.

Unsure where to put this, it could go in its own module I guess.

Fixes #5908.

Unsure where to put this, it could go in its own module I guess.
@michaelpj michaelpj requested a review from zliu41 April 17, 2024 14:43

-- | Force the evaluation of the expression delayed by the 'Delay'.
force :: Delay a -> a
force (Delay a) = a @BI.BuiltinUnit
Copy link
Member

Choose a reason for hiding this comment

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

I guess the BuiltinUnit is necessary in order for it to be compiled into delay and force?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mysteriously it compiles without it, but I think it's better to be explicit about doing the type instantiation.

import Prelude as Haskell

mustBeReplaced :: String -> a
mustBeReplaced placeholder =
error $
"The " <> show placeholder <> " placeholder must have been replaced by the \
\core-to-plc plugin during compilation."

-- | Delay evalaution of the expression inside the 'Delay' constructor.
newtype Delay a = Delay (forall b. a)
Copy link
Contributor

Choose a reason for hiding this comment

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

@michaelpj what is the purpose of forall b here? I'd appreciate a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.

@michaelpj
Copy link
Contributor Author

Huh, some tests fail. How surprising!

@michaelpj
Copy link
Contributor Author

The problem with this is that the Haskell code you write using it is not delayed when used off-chain (and remember that we are using Strict in many places). So if you e.g. try to decode some Data object off-chain, you will end up forcing the error cases early. Annoying.

I'm not entirely sure how to fix this. If we actually want something that behaves differently on- and off-chain, then we probably need to bake it into the compiler.

@Unisay
Copy link
Contributor

Unisay commented Apr 19, 2024

I'm not entirely sure how to fix this. If we actually want something that behaves differently on- and off-chain, then we probably need to bake it into the compiler.

This is how its done in Purescript https://pursuit.purescript.org/packages/purescript-control/6.0.0/docs/Control.Lazy#v:defer : a thunk is involved at construction time.

@michaelpj
Copy link
Contributor Author

Yes, but that's the unit-lambda approach which is what we were trying to avoid here. That said, I think this would still be a handy library tool even if all it does is wrap up that pattern.

@Unisay
Copy link
Contributor

Unisay commented Apr 22, 2024

That said, I think this would still be a handy library tool even if all it does is wrap up that pattern.

This is exactly how I was thinking about it. Same tool but more explicitly tagged.

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.

Add a Lazy type that compiles to delay/force
4 participants