Skip to content

Instantly share code, notes, and snippets.

@jnthn

jnthn/hmmmmm.md Secret

Last active September 2, 2020 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jnthn/1c1d717a235199bf045f9e5d3135c32a to your computer and use it in GitHub Desktop.
Save jnthn/1c1d717a235199bf045f9e5d3135c32a to your computer and use it in GitHub Desktop.
  1. Resumption is actually a syscall, dispatch-resume. Any arguments to it become the resumption arguments. The found dispatcher to resume at becomes an implicit guard.
  2. The redispatch syscall takes a dispatcher name. It obtains the arguments passed to the current call and gives them to the mentioned dispatcher. The name of the dispatcher must be a literal string constant.
  3. Both of these mechanisms involve hanging an inline cache sublist off the chosen outcome in the dispatch program. It is keyed on the bytecode address of the place doing the dispatch-resume or redispatch.
  4. callsame does nqp::dispatch('dispatch-resume'), and nextsame is similar except that it throws a return control exception.
  5. callwith does nqp::dispatch('redispatch', 'dispatch-resume'), which passes the current set of args to dispatch-resume. It's a single entry point to the dispatch mechanism, and so the result hangs off the same index.
  6. An onlystar proto with a signature that isn't | will get invoked, to enforce the proto's signature. The {*} will compile into dispatch-resume, which will then call the first candidate based on dispatch state.
  7. A proto with a body also calls dispatch-resume, and has the same kind of thing happen.
  8. Signature binds that we cannot compile today will still run the binder, but in the "just result" mode, and if it errors, will trigger the bind failed assertion. This means we have a uniform interface to reporting binder failures. Yes, it'll make errors more costly in the case we really must report them. The RakuAST goal is to Compile All The Signatures anyway...
  9. A dispatch-resume-on-bind-failure syscall will be used to indicate that a bind failure will be treated as a resumption of the enclosing dispatcher. These implicit resumes also hang off the inline cache of the outcome, and can thus stack up the guards indicating the next thing to try. We'll still peel the callframe off somehow, I guess...

Point 9 means that:

multi fac(Int $x where 0) {
    1
}
multi fac(Int $x) {
    $x * fac($x - 1)
}
fac($foo)

Then we could potentially have the specializer inline the first candidate and then rewrite the bind assert failure into a call to the second (and also inline it), or some such, which means we can get close enough to turning a multiple dispatch with where clauses and a small body into something about as efficient as a single call with an if statement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment