-
Notifications
You must be signed in to change notification settings - Fork 11
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
optimize recursion on existential types #1047
Comments
One way we could solve this could be if we see that:
Then we could possibly rewrite at the Matchless layer since we know that the type is really holding a let binding that is going to be used. Possibly we could also have existential types at the TypedExpr layer but only after type-checking, so then we could normalize this kind of code into a binding for an existential type. It could be possible to be more general here and if we can see that constructors are only created in one way, we could leverage that information to inline better. |
related to #651 |
Another idea would be to basically dynamically check patterns that look like this to see if they are "apply lambdas". So, an apply lambda (or perhaps "forwarder") is something like: But I guess that gets pretty deep into jit territory, since for it to be useful as a tail call you also have to have two implementations of the function, one with a loop and the tail call, and with a direct recursion which may consume stack. I guess optimizing the case where we know statically that there is a single constructor for an enum is maybe the more tractable approach. |
see this discussion of rules for equivalence in existential and universally quantified propositions: |
closed by #1066 |
Since we don't have existential types, we encode them with a callback approach, for instance (from #1046 )
All the
use
function ever does is directly call on two arguments closed over. So later when it is used:here note all we do is call
use((prev, fn) -> ...)
but we know that use is just going to pass two argument in:if the code were written that way, it would be tail recursive, but inside the
use
function it isn't.It seems like we should be able to see that the only instance of
FlatMap
is created by a function that just passes two values in (which would be common for such existential recursion examples). So, it would be nice to be able to rewrite the TypedExpr to remove the nesting insideuse
).It isn't obvious though. Maybe if we had existential types after type checking, at the TypedExpr layer, we could rewrite functions like
use((prev, fn) -> ...
to(prev, fn): exists t. (Eval[t], t -> Eval[a]) = use((prev, fn) -> (prev, fn))
then see that we can eliminate theexists t.
from what comes next in a way that preventst
from escaping.The text was updated successfully, but these errors were encountered: