Skip to content

Instantly share code, notes, and snippets.

@sgolemon
Last active May 26, 2020 18:02
Show Gist options
  • Save sgolemon/5a541fa86be682692c0276ac8209d18d to your computer and use it in GitHub Desktop.
Save sgolemon/5a541fa86be682692c0276ac8209d18d to your computer and use it in GitHub Desktop.
Typed callables (random musings)
We can already do this:
function foo(Callable $bar) {
$bar("Hellow World");
}
But that requires foo() to make assumptions about the callback its received.
If it's invoked with a callback that doesn't take precisely one string argument, then things will break.
function ItakeNoArgs() {}
foo('ItakeNoArgs');
foo('IdontEvenExist');
foo(function($a, $b) { /* I take more than one args */ });
foo(function(array $x) { /* I don't allow strings */ });
What if we could type our callbacks?
HackLang has this: https://docs.hhvm.com/hack/functions/introduction#function-types
function foo((function(string): void) $bar) {
$bar("Hello World");
}
Even if we use `fn` as with short lambdas, those signatures get pretty heavy, pretty quickly.
HackLang addresses that problem with aliases: https://docs.hhvm.com/hack/types/type-aliases
type BarCallback = function(string): void;
function foo(BarCallback $bar) {...}
A possible alternative syntax might be prototype declarations:
function BarCallback(string): void;
function foo(BarCallback $bar) {..}
Ultimately, these all have the problem of runtime enforcement where the callable
has to be resolved to reflectable signatures.
Object instances implemeting the __invoke() magic method are probably the simplest to identify.
Class/object methods have the issue of visibility. Even if the method isn't visible to the
function receiving the callable, it may be valid to pass it through to a subordinate method
which does have visibility.
Global function (string) callables are the most complicated as they lack autoloading,
and namespace resolution is a question without an easy ansewr.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment