-
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
Allow for retrieving the index of a SOP constructor #6653
Comments
@effectfully Thanks for taking the time to write this up. We are very appreciative of the time you have personally spent to help bring more utility to SOPs. It's fair that you mark this issue as low priority, making I wouldn't completely write off SOPs yet though, as they do have their use-case: efficient multiple branches. On X I mentioned two issues that could be solved with a builtin that can retrieve the case index:
1. comparing the indexWithout such a builtin function, it will be easier to keep using
2. combing multiple SOPsThis is easier to discuss with an example, typically seen in real-life Helios code. Assume we the following enum:
We want to compare the state of a given UTxO being spent with the state of the return UTxO: so Let's assume we have the following valid state evolution:
The equivalent in code:
If the State is kept as Without default case (current situation)If the State is first converted to SOP, using
Although this particular example doesn't seem so extreme, you should imagine many more variants, which makes the generated code blow up with many duplicate branches. In summary: we currently consider SOPs only viable for branching over a single With simple default caseI'm assuming the last case would always be used as the default. This wouldn't improve anything for this example because there is no situation where 2 or mores final branches are the same. So for this example implementing a default case isn't worth the effort. With fancy default caseThis proposal doesn't seem very composable. Wouldn't it then make more sense to implement a variable-args version of ifThenElse instead? The arguments of such a term could also be implicitly delayed:
I also think this would be greatly beneficial to languages with advanced pattern matching syntax like Aiken. To be honest I think this is too high-level for UPLC, though there seems to be some support for it: #6578 With a builtin that can retrieve the case indexWe would be able to keep the A function for retrieving the constr args would also be needed though. Are SOPs worth it?SOPs can currently provide benefit in only a few situations. Are there other situations that I hadn't thought of? Sorry for being frank, but maybe SOPs aren't worth the complexity they introduce to the CEK machine, and should be removed for UPLC version 4. The branching functionality of SOPs could simply be replaced by allowing builtin lists to contain lambdas, and allowing a way to define such a list literally (eg. I also agree with @nau that we should use either only |
Yes, but this is exactly what I want to bring to
Thanks a lot for providing the example, I agree with your assessment that my idea as written of using the default case is basically useless. I mixed up pattern matching in normal languages and UPLC and suggested something stupid because of that.
Well, as I'm arguing in the issue description, such builtins have never made it past peer review. Given the relative unimportance of SOPs, I doubt this time would be any different.
Frankness is always appreciated, we're very much interested in users providing honest feedback as that allows us to improve the product.
I've been gravitating towards the same conclusion. If we can make Anyway, we are very much focused on making
Probably not gonna happen, because it's hard to fit into the current design of UPLC. And if it did, everybody would start complaining that now you can have a list of
😛 Thank you for this discussion, it really helped me to start disliking SOPs more 🙂 |
Making |
Helios folks propose to introduce a builtin allowing one to get
i
fromTerm.Constr i args
.Their reasoning is that sometimes one only needs to check whether the constructor is a specific one, instead of providing a branch for every single constructor. E.g. if you have a big sum type like
then you can define equality checking for such a type in linear amount of matches in, say, Plinth:
but on the UPLC level this will give you a quadratic number of branches, because for each
Ci
to the left of==
you'll need to explicitly handle all ofC1
...Cn
, because acase
has to explicitly handle all possible constructors and there's can't be a catch-all clause.There's a number of issues with the proposal, though. Firstly, what if those
C*
constructors carry some arguments? How will we extract them out of there if we only know the index of the constructor?Secondly, such a builtin would break parametricity, it's the same issues as we relentlessly discussed in the
equalsCanonical
PR and in #5776 + #6225. I.e. we've already given up on important things because of the parametricity issue, so it's unlikely we're going to revert on that just for the purpose of having a builtin returning the index of a SOP.Now given that SOPs are basically on par with builtins and we seem to have a plan on making
Data
as fast as SOPs, do we even need to worry about SOPs at this point? Maybe it'll turn out that just having fastData
is enough? Sure you can't put functions intoData
and such, but does anybody actually care about that? Anyway, I digress.What we could have is
case
with a default clause. That'd solve the equality issue described above. Helios folks claim it's not enough in the general case though:so naturally I wonder what those extreme cases are.
But let's say that instead of introdcing a basic default clause, we introduce a fancy default clause giving you access to the index of the constructor. It's gonna be a bit weird, because the AST doesn't know anything about integers, but let's say we'll pull it off somehow. Would it be good or weird? It's pretty much reflection at this point and UPLC wasn't designed with any reflection capabilities in mind, so maybe that'll screw the metatheory up somehow?
Anyway, I'll mark this as low-priority, because speeding up
Data
is far more important, but now that Helios folks told us about this problem I do find the lack of default clauses unfortunate, so maybe we should do something about it.The text was updated successfully, but these errors were encountered: