-
Notifications
You must be signed in to change notification settings - Fork 483
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
[Builtins] Add 'Proxy' to the default universe #4337
[Builtins] Add 'Proxy' to the default universe #4337
Conversation
This would need Plutus V2, FWIW. This all makes sense from an engineering perspective, I think my reservation with this stuff is it feels like there's a theoretical hole we haven't quite filled about how polymorphic builtin types can only be instantiated at builtin types, and how we reconcile that with the typesystem that we have... |
Why? It's just a new built-in type and a new built-in function. We don't need to drop the old
Where do you see a hole?
|
Ah, I was assuming we'd drop them. Yes, that's true.
We need to be able to specify it is why! Kenneth is already having a lot of difficulty specifying the current version, and I think that's without allowing for the possibility of something like
Hmmm.... And how do you get such a thing? I think the answer is: only by making it as a literal constant. There's something a bit funny here: we could do that today to get rid of the various |
These are good intentions, but polymorphic built-in types don't come for free. Without them we could have a builtins machinery that is inline with the rest of the type system of Plutus, but with them things get trickier. It's similar to how we could've avoided the entire extensible built-in types machinery if we were to hardcode an inlined version of How would you allow something like a built-in
If we're able to compile lists and operations over them, there shouldn't be any trouble compiling |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all seems to make sense, but I wonder if we really need it yet. It's annoying that we're stuck with mkNilData
and mkNilPairData
forever and we can't just use mkNil
instead. I'd be inclined to put this on ice until we actually need it, if we decide we do at some point.
[Edit: see a later comment where I realise that most of this is rubbish.]
What kind of things do you see us using the Proxy
type for in practice? I'm wondering if we can get away without needing it at all. To use mkNil
to create an empty list of integers, we first have to instantiate it at type integer
, and then we have to apply it to a constant of type proxy(integer)
(I even managed to do this successfully after a bit of fiddling with the parser). Could we instead have a polymorphic nullary mkNil
builtin that we just instantiate to get an empty list immediately without needing Proxy
types and values to be visible in PLC at all? It may be that this approach doesn't give us the flexibility that Proxy
does, so I'm wondering what a plausible use case for the full Proxy
machinery might be.
I have a vague idea that there might have been some objection to having nullary builtins, although I don't immediately see what the problem would be. Maybe that would torpedo the suggestion above. [Later: I see a comment near the definition of mkNilData
saying "nullary builtins don't work", but it doesn't say why. Is that a fundamental restriction? Even if it is, could we define a mkNil
of type [forall a, unit] -> list(a)
?]
I also haven't thought through how to specify the semantics of all this yet. I think nullary builtins would be OK, but I'm not so sure about Proxy, although that might still fit into the present framework.
toBuiltinMeaning MkNil = | ||
makeBuiltinMeaning | ||
nilPlc | ||
(runCostingFunOneArgument . paramMkNilData) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strictly this would need its own cost model parameters instead of re-using the ones for mkNilData
, and that would require us to add new benchmarks for mkNil
. However, I'm pretty certain that that would make no difference at all since this is doing almost no work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we express the meanings of mkNilData
and mkNilPairData
directly in terms of mkNil
? Maybe then we'd just need one benchmark for all three functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strictly this would need its own cost model parameters instead of re-using the ones for
mkNilData
, and that would require us to add new benchmarks formkNil
Yes, I'm just being sloppy here.
Could we express the meanings of
mkNilData
andmkNilPairData
directly in terms ofmkNil
?
Probably not. They are very similar, but not to the point of the first two being an instance of the last one.
@@ -109,6 +110,9 @@ deriving via AsRead Integer instance Parsable Integer | |||
deriving via AsRead () instance Parsable () | |||
deriving via AsRead T.Text instance Parsable T.Text | |||
|
|||
instance Parsable (Proxy a) where | |||
parse = error "Parsing for Proxy is not implemented" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be easy to do, wouldn't it? It'd just be checking whether or not a string was "proxy" (or "Proxy" or whatever).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, just being sloppy.
show DefaultUniData = "data" | ||
show DefaultUniProtoProxy = "proxy" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need some code for parsing proxy
just below as well? (Also, do we really want what the Parsable instance is doing for the pair and list types, or is that code not supposed to be used?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep.
(Also, do we really want what the Parsable instance is doing for the pair and list types, or is that code not supposed to be used?)
I don't really know, that's up to @thealmarty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Parsable instance will be gone in the new parsers. The new parsers won't be dealing with data structures yet. It'll be in another PR. We can think about what we want then.
I now realise that much of what I wrote earlier was nonsense. My thinking was that many of the things one would once have used I was a bit worried that adding this to the specification would need some kind of special case, but now I think that it would fit into the existing framework without having to modify anything. I'd still be inclined to keep it in reserve, to be rolled out if at some point we decide to add some new polymorphic built-in type that needs the functionality. |
In the builtins-specification that's brewing in my head (it would have to be for V2), I think there's a nice way to incorporate this without including it in the UPLC specification: |
Yes, exactly.
I believe so, yes. It's just another polymorphic built-in type, nothing more fancy than the type of lists. It is not handled in any special case. |
Let's close this one for now and reopen when we need it. |
This shows how to add
Proxy
to the default universe, so that we can have only only one built-inMkNil
and express the two that we currently have in terms of it.This is unpolished, 'cause I'm not sure if we want this or not, I just thought it would be easy to implement it, so I did that.